bugGNU roff - Bugs: bug #67612, [PATCH] [gropdf] exits with...

 
 

bug #67612: [PATCH] [gropdf] exits with nonzero status on warning

Submitter:  Dave <barx>
Submitted:  Fri 17 Oct 2025 06:56:27 PM UTC
   
 
Category:  Driver gropdf Severity:  3 - Normal
Item Group:  Warning/Suspicious behaviour Status:  Fixed
Privacy:  Public Assigned to:  gbranden
Open/Closed:  Closed Planned Release:  1.24.0
* Mandatory Fields

Post a Comment

Add a New Comment Rich Markup
   

Discussion

Jump to the original submission

Tue 18 Nov 2025 05:49:08 PM UTC, comment #35: 


commit 48ab4912bb9fb7a23ee7814544207d4d72efbf62
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
Date:   Mon Nov 17 21:20:21 2025 -0600

    [gropdf]: Fix Savannah #67612.

    * src/devices/gropdf/gropdf.pl (Warn): Set exit status to 1, not 2, if
      the scalar `warnexit` (set by the `-W` command-line option) is truthy.

      (usage): Exit with status 2, not 1, on usage errors.

    * src/devices/gropdf/gropdf.1.man (Options, Exit status): Update
      documentation accordingly.

    Fixes <https://savannah.gnu.org/bugs/?67612>.  Thanks to Dave Kemper for
    the report and to him and Deri for the code review.


G. Branden Robinson <gbranden>
Group administrator
Mon 17 Nov 2025 10:41:39 PM UTC, comment #34: 

Thanks, Deri.

Snagging back onto my plate.

I think I'll likely push today, including this patch, but omit the stuff that Dave and I are arguing about.  I want to give Werner time to reply to a recent petition for expression of authorial intent.

G. Branden Robinson <gbranden>
Group administrator
Mon 17 Nov 2025 10:29:09 PM UTC, comment #33: 

Branden, looks ok, yes please push for me.

Deri James <deri>
Group Member
Mon 17 Nov 2025 06:14:05 PM UTC, comment #32: 

Deri, do you have any comments on v3 of the patch in comment #30?

Would you like me to include it in my next push?

G. Branden Robinson <gbranden>
Group administrator
Fri 07 Nov 2025 07:05:50 PM UTC, comment #31: 


comment #28:

> Fair point.  My inclination in that case would be to document the meaning of the function's parameter once at the function definition, rather than at each call site, but given this function is called exactly twice, that seems to make no practical difference.


Yeah, and that's an argument for Python-style named arguments, which I'm not sure that Perl versions as old as we want to be portable to (5.8) are supported by.

> > Historically, both are pretty sloppily typed.
>
> I think that misses the point: C/C++ are weakly typed, and Perl is not typed.  Adding a new variable type to a weakly typed language is a language expansion; adding one to an untyped language is a language redesign, because there's no framework to "add" to.


One could fairly say that I'll never forgive C for deciding that BCPL was a good baseline to start from, and I'll never forgive Stroustrup for not just reimplementing Ada.

On the other hand, if he had, we might not ever have gotten GNAT, and Ada would be even more poorly known than it is.

G. Branden Robinson <gbranden>
Group administrator
Fri 07 Nov 2025 07:02:43 PM UTC, comment #30: 

comment #29:

> Huh, I got so swept up in coding style details I failed to notice the content issues in the man page's -W description.
> * The patch should generalize from "if font embedding fails" to something like "if gropdf emits any warnings" (per comment #21).
> * I'd also suggest clarifying or removing "Normally, gropdf issues a warning diagnostic and proceeds."  As far as I can tell, -W won't make gropdf exit any earlier, just with different status.


Good points, both.

Patch v3:


$ git diff
diff --git a/src/devices/gropdf/gropdf.1.man b/src/devices/gropdf/gropdf.1.man
index 09b5d191a..87ccd025c 100644
--- a/src/devices/gropdf/gropdf.1.man
+++ b/src/devices/gropdf/gropdf.1.man
@@ -316,11 +316,7 @@ .SH Options
 .
 .TP
 .B \-W
-Exit with failure status if font embedding fails.
-.
-Normally,
-.I gropdf
-issues a warning diagnostic and proceeds.
+Exit with failure status if any warnings are issued.
 .
 .
 .\" .TP
@@ -1944,17 +1940,19 @@ .SH "Exit status"
 .IP 0
 .I gropdf
 successfully produced a PDF document.
+.
+.
 .IP 1
 .I gropdf
 experienced a critical error,
-or could not interpret its arguments.
-No PDF was produced,
-or the document produced will be unusable.
+or warnings were emitted and the
+.B \-W
+option was specified.
+.
+.
 .IP 2
 .I gropdf
-emitted warnings.
-The document produced may be usable,
-but may fail to render as desired.
+could not interpret its command-line arguments.
 .
 .
 .br
diff --git a/src/devices/gropdf/gropdf.pl b/src/devices/gropdf/gropdf.pl
index d0da52c42..db0562c9c 100644
--- a/src/devices/gropdf/gropdf.pl
+++ b/src/devices/gropdf/gropdf.pl
@@ -461,7 +461,7 @@ sub usage
 "Translate the output of troff(1) into Portable Document Format.\n" .
 "See the gropdf(1) manual page.\n";
     }
-    exit($had_error);
+    exit($had_error ? 2 : 0);
 }

 my $fd;
@@ -498,7 +498,7 @@ if (!GetOptions('F=s' => \@fdlist, 'I=s' => \@idirs, 'l' => \$frot,
     'e' => \$embedall, 'y=s' => \$Foundry, 's' => \$stats, 'W' => \$warnexit,
     'u:s' => \$unicodemap))
 {
-    &usage(1);
+    &usage(1); # had error
 }

 unshift(@idirs,'.');
@@ -3197,7 +3197,7 @@ sub Warn
     unshift(@_, "warning: ");
     my $msg=join('',@_);
     Msg(0,$msg);
-    $xitcd=2 if $warnexit;
+    $xitcd=1 if $warnexit;
 }

 sub Die


G. Branden Robinson <gbranden>
Group administrator
Fri 07 Nov 2025 06:30:19 PM UTC, comment #29: 

Huh, I got so swept up in coding style details I failed to notice the content issues in the man page's -W description.

  • The patch should generalize from "if font embedding fails" to something like "if gropdf emits any warnings" (per comment #21).
  • I'd also suggest clarifying or removing "Normally, gropdf issues a warning diagnostic and proceeds."  As far as I can tell, -W won't make gropdf exit any earlier, just with different status.
Dave <barx>
Group Member
Fri 07 Nov 2025 06:03:03 PM UTC, comment #28: 

comment #27:

> `&usage(1);` looked to me like it might be saying "throw the
> usage message and exit with status 1".


Fair point.  My inclination in that case would be to document the meaning of the function's parameter once at the function definition, rather than at each call site, but given this function is called exactly twice, that seems to make no practical difference.

> Historically, both are pretty sloppily typed.


I think that misses the point: C/C++ are weakly typed, and Perl is not typed.  Adding a new variable type to a weakly typed language is a language expansion; adding one to an untyped language is a language redesign, because there's no framework to "add" to.

Dave <barx>
Group Member
Fri 07 Nov 2025 01:42:51 PM UTC, comment #27: 

comment #26:

> Thanks.  I think no longer changing the 1 to a 2 at the call site makes the comment unnecessary, but I won't object to too much code commenting.


The reason I don't is for the same reason I got confused in the first place: `&usage(1);` looked to me like it might be saying "throw the usage message and exit with status 1".

> The parallel isn't really valid: unlike C and C++ variables, Perl variables are untyped,


Valid enough, in my bigoted strong-typing opinion.  Historically, both are pretty sloppily typed.

The whole point of function prototypes in ANSI C was to add a facility to the language by which the cardinality of function arguments and their types could be checked at all.

London and Reiser's paper on porting Unix to the VAX-11 is useful for insight into just how loose a ship Dennis Ritchie ran.


G. Branden Robinson <gbranden>
Group administrator
Thu 06 Nov 2025 09:11:27 PM UTC, comment #26: 

Thanks.  I think no longer changing the 1 to a 2 at the call site makes the comment unnecessary, but I won't object to too much code commenting.

comment #24:

> Perl, like C before it and C++ alongside it, has shown a
> stubborn reluctance to embrace an explicit Boolean type.


The parallel isn't really valid: unlike C and C++ variables, Perl variables are untyped, so the concept of a boolean variable is meaningless in Perl.  It'd be weird to introduce a typing system where a variable is either boolean or nonboolean; if you introduce types into Perl variables, you'd want to cover all types, and then you're looking at a language redesign that makes it not really Perl anymore.

Dave <barx>
Group Member
Thu 06 Nov 2025 06:13:23 PM UTC, comment #25: 

Patch v2:


diff --git a/src/devices/gropdf/gropdf.1.man b/src/devices/gropdf/gropdf.1.man
index 09b5d191a..20cf1f37c 100644
--- a/src/devices/gropdf/gropdf.1.man
+++ b/src/devices/gropdf/gropdf.1.man
@@ -1944,17 +1944,19 @@ .SH "Exit status"
 .IP 0
 .I gropdf
 successfully produced a PDF document.
+.
+.
 .IP 1
 .I gropdf
 experienced a critical error,
-or could not interpret its arguments.
-No PDF was produced,
-or the document produced will be unusable.
+or warnings were emitted and the
+.B \-W
+option was specified.
+.
+.
 .IP 2
 .I gropdf
-emitted warnings.
-The document produced may be usable,
-but may fail to render as desired.
+could not interpret its command-line arguments.
 .
 .
 .br
diff --git a/src/devices/gropdf/gropdf.pl b/src/devices/gropdf/gropdf.pl
index d0da52c42..db0562c9c 100644
--- a/src/devices/gropdf/gropdf.pl
+++ b/src/devices/gropdf/gropdf.pl
@@ -461,7 +461,7 @@ sub usage
 "Translate the output of troff(1) into Portable Document Format.\n" .
 "See the gropdf(1) manual page.\n";
     }
-    exit($had_error);
+    exit($had_error ? 2 : 0);
 }

 my $fd;
@@ -498,7 +498,7 @@ if (!GetOptions('F=s' => \@fdlist, 'I=s' => \@idirs, 'l' => \$frot,
     'e' => \$embedall, 'y=s' => \$Foundry, 's' => \$stats, 'W' => \$warnexit,
     'u:s' => \$unicodemap))
 {
-    &usage(1);
+    &usage(1); # had error
 }

 unshift(@idirs,'.');
@@ -3197,7 +3197,7 @@ sub Warn
     unshift(@_, "warning: ");
     my $msg=join('',@_);
     Msg(0,$msg);
-    $xitcd=2 if $warnexit;
+    $xitcd=1 if $warnexit;
 }

 sub Die


G. Branden Robinson <gbranden>
Group administrator
Thu 06 Nov 2025 06:11:40 PM UTC, comment #24: 

comment #23:

> Currently, usage() takes ones parameter, $had_error, which is passed unchanged to exit().  The comment #22 patch appears to change usage() to treat its parameter as a boolean instead of an exit value:


> -    exit($had_error);
> +    exit($had_error ? 2 : 0);


...ah.  With a name like `had_error`, I assume that this scalar was of Boolean sense.

Perl, like C before it and C++ alongside it, has shown a stubborn reluctance to embrace an explicit Boolean type.

https://perlmaven ... an-values-in-perl

> while simultaneously changing one of the usage() call sites to pass what looks like a specific exit value:


> -    &usage(1);
> +    &usage(2);


> Either of the above two changes by itself would change the exit value from 1 to 2, so one of the changes appears to be unnecessary.


Right.

> If this isn't an error, it begs for an explanatory comment.


I'll give it one.

G. Branden Robinson <gbranden>
Group administrator
Thu 06 Nov 2025 05:59:37 PM UTC, comment #23: 

Currently, usage() takes ones parameter, $had_error, which is passed unchanged to exit().  The comment #22 patch appears to change usage() to treat its parameter as a boolean instead of an exit value:

-    exit($had_error);
+    exit($had_error ? 2 : 0);

while simultaneously changing one of the usage() call sites to pass what looks like a specific exit value:

-    &usage(1);
+    &usage(2);

Either of the above two changes by itself would change the exit value from 1 to 2, so one of the changes appears to be unnecessary.  If this isn't an error, it begs for an explanatory comment.

Dave <barx>
Group Member
Thu 06 Nov 2025 05:28:25 PM UTC, comment #22: 

comment #21:

> It appears that commit 72911e55b does what I suggested in the last sentence of comment #18: making all warnings produce a nonzero exit code.  The relevant change in "sub Warn" is:


> -    $xitcd=2;
> +    $xitcd=2 if $warnexit;


> However, the -W description in the man page still says the option is effective "if font embedding fails," which no longer appears to be a restriction.
>
> The "Exit status" section of the man page also states the exit status is 2 when "gropdf emitted warnings," although this appears to no longer be the default behavior.


Here's a patch to tidy this stuff up.

Deri, do you have any objections?


diff --git a/src/devices/gropdf/gropdf.1.man b/src/devices/gropdf/gropdf.1.man
index 09b5d191a..20cf1f37c 100644
--- a/src/devices/gropdf/gropdf.1.man
+++ b/src/devices/gropdf/gropdf.1.man
@@ -1944,17 +1944,19 @@ .SH "Exit status"
 .IP 0
 .I gropdf
 successfully produced a PDF document.
+.
+.
 .IP 1
 .I gropdf
 experienced a critical error,
-or could not interpret its arguments.
-No PDF was produced,
-or the document produced will be unusable.
+or warnings were emitted and the
+.B \-W
+option was specified.
+.
+.
 .IP 2
 .I gropdf
-emitted warnings.
-The document produced may be usable,
-but may fail to render as desired.
+could not interpret its command-line arguments.
 .
 .
 .br
diff --git a/src/devices/gropdf/gropdf.pl b/src/devices/gropdf/gropdf.pl
index d0da52c42..71f00633a 100644
--- a/src/devices/gropdf/gropdf.pl
+++ b/src/devices/gropdf/gropdf.pl
@@ -461,7 +461,7 @@ sub usage
 "Translate the output of troff(1) into Portable Document Format.\n" .
 "See the gropdf(1) manual page.\n";
     }
-    exit($had_error);
+    exit($had_error ? 2 : 0);
 }

 my $fd;
@@ -498,7 +498,7 @@ if (!GetOptions('F=s' => \@fdlist, 'I=s' => \@idirs, 'l' => \$frot,
     'e' => \$embedall, 'y=s' => \$Foundry, 's' => \$stats, 'W' => \$warnexit,
     'u:s' => \$unicodemap))
 {
-    &usage(1);
+    &usage(2);
 }

 unshift(@idirs,'.');
@@ -3197,7 +3197,7 @@ sub Warn
     unshift(@_, "warning: ");
     my $msg=join('',@_);
     Msg(0,$msg);
-    $xitcd=2 if $warnexit;
+    $xitcd=1 if $warnexit;
 }

 sub Die



G. Branden Robinson <gbranden>
Group administrator
Thu 06 Nov 2025 04:52:06 PM UTC, comment #21: 

It appears that commit 72911e55b does what I suggested in the last sentence of comment #18: making all warnings produce a nonzero exit code.  The relevant change in "sub Warn" is:

-    $xitcd=2;
+    $xitcd=2 if $warnexit;

However, the -W description in the man page still says the option is effective "if font embedding fails," which no longer appears to be a restriction.

The "Exit status" section of the man page also states the exit status is 2 when "gropdf emitted warnings," although this appears to no longer be the default behavior.

Dave <barx>
Group Member
Tue 04 Nov 2025 06:00:59 PM UTC, comment #20: 

Downgraded two warnings to Notice, since PDF produced will be fine. Reintroduced -W flag to makefiles so gropdf will exit 2 if warning emitted. Without -W warnings ar non-fatal.

commit 72911e55b7b99edbc80055ec9a59d1d9ab30ba15
Author: Deri James <deri@chuzzlewit.myzen.co.uk>
Date:   Tue Nov 4 17:25:54 2025 +0000

    [gropdf]: Reinstate -W to set exit code 2 on warning, and
    downgrade two Warnings to Notices.

    * src/devices/gropdf/gropdf.pl: Do it.

    Fixes https://savannah.gnu.org/bugs/?67612

    Thanks to Dave and Branden.

commit d0e29bc60cec8fb23c847458af518b5dc5cc740d
Author: Deri James <deri@chuzzlewit.myzen.co.uk>
Date:   Tue Nov 4 17:13:24 2025 +0000

    Reinstate using -W flag when building pdfs. Baby was thrown
    out with the bathwater by me.

    * doc/doc_am:
    * contrib/mom/mom.am: Reinstate -W flag to provide exit code
    if a warning is produced during build.

    Thanks to Dave for report in:-

    https://savannah.gnu.org/bugs/?67612

    and apologies to Branden for exfiltrating the baby.


Deri James <deri>
Group Member
Sun 02 Nov 2025 12:05:51 PM UTC, comment #19: 

comment #18:

> I don't know how to provoke a font-embedding failure, so I
> can't test this.


Strike that; it turns out I don't need to know how to do this in order to demonstrate that the -W switch doesn't behave as documented.

$ $HOME/groff/build/gropdf --version
GNU gropdf (groff) version 1.23.0.4049-1828-modified
$ $HOME/groff/build/gropdf -W
Unknown option: W
usage: gropdf [-dels] [-F font-directory] [-I inclusion-directory] [-p paper-format] [-u [cmap-file]] [-y foundry] [file ...]
usage: gropdf {-v | --version}
usage: gropdf --help


Dave <barx>
Group Member
Sun 02 Nov 2025 11:55:44 AM UTC, comment #18: 

comment #2:

> I think a better solution would be for gropdf to support a
> command-line option or environment variable that caused it to
> treat warnings as fatal problems.


Fun fact: gropdf already allegedly has such an option, though with limited scope.  The man page documents the -W switch as, "Exit with failure status if font embedding fails.  Normally, gropdf issues a warning diagnostic and proceeds."

Why do I say "allegedly"?  Well, I don't know how to provoke a font-embedding failure, so I can't test this.  But the code makes me suspect this doesn't work as documented: this condition seems to call Warn(), which we know from comment #4 always exits with failure status.

$ fgrep -C3 'unable to embed' src/devices/gropdf/gropdf.pl
        }
        else
        {
            Warn("unable to embed font file for '$fnt{internalname}'"
            . " ($ofontnm) (missing entry in 'download' file?)")
            if $embedall;
        }

So perhaps the -W switch could be repurposed into doing what is documented, but for all warnings rather than only font-embedding ones.

Dave <barx>
Group Member
Fri 31 Oct 2025 05:35:30 AM UTC, comment #17: 

comment #16:

> I have a pending change to "downgrade" the two messages Dave
> identifies as not really warnings to "Notices",


Excellent.

Still, I think there's a design question to ponder.

> The change in behaviour (setting an exit code on warnings) was added so that
> make would abort if gropdf reported a warning, at Branden's suggestion.


I think most software exits with 0 if only warnings are emitted.  (This does not appear to be addressed in the GNU Coding Standards.)  I reiterate my point in comment #1, that compiler warnings are designed to exit as success, so as to allow "make" to continue.  So I don't think gropdf should violate this convention without good reason.

Its exit code was changed (in the commit cited in comment #1) as part of the solution to bug #67268, which deep-dives into build-system arcana that's over my head.  So maybe there is good reason here.  But would it be a better design to make the user explicitly request that warnings exit as errors?  (This is a genuine question; I'm not trying to put a thumb on either side of the scale.)

> Also, this only affects situations where groff is used in a
> workflow where the exit status is checked, which is a subset
> of usual uses of groff - to produce a single document from the
> command line.


I encountered it producing a single document from the command line.  It's just that, when editing and regenerating a document many times, it's often easier to set up a trivial Makefile and type "make" rather than "groff -Tpdf filename" each time.  Granted, the PDF is successfully generated, but "make" reports a failure each time.

Dave <barx>
Group Member
Thu 30 Oct 2025 11:36:38 AM UTC, comment #16: 

On Thursday, 30 October 2025 08:43:20 GMT G. Branden Robinson wrote:

> Follow-up Comment #15, bug #67612 (group groff):
>
>
> comment #14:
>
> > Thanks, Deri, this fully explains the results I'm seeing.
>
> What needs to be done to resolve this ticket?



I have a pending change to "downgrade" the two messages Dave identifies as not
really warnings to "Notices", since they are informational rather than
reporting a problem with the produced pdf, and so  will not cause a non-zero
exit.


> Improve the documentation?
>
> Add a command-line option or environment variable to support this "treat
> warnings as errors" behavior, and change the default to not do so?



The change in behaviour (setting an exit code on warnings) was added so that
make would abort if gropdf reported a warning, at Branden's suggestion. I
don't mind if the behaviour is selectable in some way, but I think after the
"downgrading" only messages which denote possible problems with the produced
pdf will result in non-zero exit status. Also, this only affects situations
where groff is used in a workflow where the exit status is checked, which is a
subset of usual uses of groff - to produce a single document from the command
line.

> Both?  Something else?
>



Deri James <deri>
Group Member
Thu 30 Oct 2025 08:43:14 AM UTC, comment #15: 


comment #14:

> Thanks, Deri, this fully explains the results I'm seeing.


What needs to be done to resolve this ticket?

Improve the documentation?

Add a command-line option or environment variable to support this "treat warnings as errors" behavior, and change the default to not do so?

Both?  Something else?

G. Branden Robinson <gbranden>
Group administrator
Thu 30 Oct 2025 03:20:55 AM UTC, comment #14: 

comment #13:

> if your previous groff is in /usr/share/groff then gropdf will
> fail unless you have used --prefix=/usr when configure was run


Thanks, Deri, this fully explains the results I'm seeing.

Dave <barx>
Group Member
Mon 27 Oct 2025 01:38:27 PM UTC, comment #13: 

The GROFF_FONT_PATH setting in the test-groff you are using will cause troff to use the fonts in build/font and the lack of a -F flag will cause gropdf to use the system locations (probably /usr/local/share/groff) to find the fonts and download file.

It has nothing to do with whether you build in or out of tree, without the flag gropdf will be looking at a different font directory than troff does (because the GROFF_FONT_PATH is not set in the environment in which gropdf runs), Quite often this may "work" if you have a previous installed groff version in /usr/local/share but if your previous groff is in /usr/share/groff then gropdf will fail unless you have used --prefix=/usr when configure was run - which is unlikely if you are simply building groff to test a recent change, without intending to install it.

Deri James <deri>
Group Member
Sun 26 Oct 2025 09:04:10 PM UTC, comment #12: 

comment #11:

> > > Lacking a test-gropdf analogue to the test-groff script, running the
> > > latest
> > > gropdf directly is not straightforward.
> > >
> > > $ echo 'Yo!' | $HOME/groff/build/test-groff -Z -Tpdf |
> > > $HOME/groff/build/gropdf
> > > gropdf: fatal error: failed to open 'download' file
> > >
> > >
> > > There's probably a way to make it work, but it's not worth my time to
> > > figure out, since all I care about is "is it 0 or not-0?"
> >
> > Hmm.  This works for me:
> >
> >
> > $ echo 'Yo!' | ./build/test-groff -Z -Tpdf | ./build/gropdf >/dev/null
> > $ echo $?
> > 0
>
> You may need "-F build/font" on the gropdf invocation, otherwise gropdf will be using fonts in the current system directories, whereas groff (via test-groff) uses the fonts in build/font.


Good point, but it doesn't change the outcome for me.


$ echo 'Yo!' | ./build/test-groff -Z -Tpdf | ./build/gropdf -F ./font -F ./build/font >/dev/null
$ echo $?
0


(Since I use separate source and build trees, I directed gropdf to both...though to be fair I don't see anything in the *source* font/devpdf directory that the output driver can directly use.)

G. Branden Robinson <gbranden>
Group administrator
Sun 26 Oct 2025 01:20:37 PM UTC, comment #11: 


> > Lacking a test-gropdf analogue to the test-groff script, running the
> > latest
> > gropdf directly is not straightforward.
> >
> > $ echo 'Yo!' | $HOME/groff/build/test-groff -Z -Tpdf |
> > $HOME/groff/build/gropdf
> > gropdf: fatal error: failed to open 'download' file
> >
> >
> > There's probably a way to make it work, but it's not worth my time to
> > figure out, since all I care about is "is it 0 or not-0?"
>
> Hmm.  This works for me:
>
>
> $ echo 'Yo!' | ./build/test-groff -Z -Tpdf | ./build/gropdf >/dev/null
> $ echo $?
> 0


You may need "-F build/font" on the gropdf invocation, otherwise gropdf will be using fonts in the current system directories, whereas groff (via test-groff) uses the fonts in build/font.

Deri James <deri>
Group Member
Sun 26 Oct 2025 12:59:48 PM UTC, comment #10: 

comment #9:

> Oh, I misunderstood which command's exit status you were speaking of.


I'm speaking of gropdf's exit status.  But my examples show it as filtered through groff.  Sorry for not being clear about that.

> Is your devpdf/dowload situation damaged?


Possibly.  My system does have a /usr/share/groff/site-font/devpdf/download.  However, gropdf runs without complaint when test-groff invokes it, so a damaged "download" doesn't seem to explain it.  In any case, not really worth it to me to delve into.

Dave <barx>
Group Member
Sat 25 Oct 2025 01:01:49 AM UTC, comment #9: 


comment #8:

> comment #7:
> > Is use of exit status 4 necessary?  Is gropdf already using
> > status 3 for something?
>
> The exit status is coming from groff, not gropdf; I presume groff is munging it in some manner as the documentation you quoted implies, although the specific munging does not seem to be exactly in line with that snippet, unless one reads "setting bit 2 if a command exited with a failure status" as also implying "and clearing whatever bits the failing command returned on exit."


Oh, I misunderstood which command's exit status you were speaking of.
 

> Lacking a test-gropdf analogue to the test-groff script, running the latest gropdf directly is not straightforward.


> $ echo 'Yo!' | $HOME/groff/build/test-groff -Z -Tpdf | $HOME/groff/build/gropdf
> gropdf: fatal error: failed to open 'download' file


> There's probably a way to make it work, but it's not worth my time to figure out, since all I care about is "is it 0 or not-0?"


Hmm.  This works for me:


$ echo 'Yo!' | ./build/test-groff -Z -Tpdf | ./build/gropdf >/dev/null
$ echo $?
0


Let me see if it still works when my current working directory is in some arbitrary place.


$ echo 'Yo!' | ~/src/GIT/groff/build/test-groff -Z -Tpdf | ~/src/GIT/groff//build/gropdf >/dev/null
$ echo $?
0


This is groff HEAD, as pushed today.  No new commits in my working copy yet.  But I also can't think of any recent commits that would have changed this.  (pdfmom is not involved.)

Is your devpdf/dowload situation damaged?

G. Branden Robinson <gbranden>
Group administrator
Fri 24 Oct 2025 02:35:39 AM UTC, comment #8: 

comment #7:

> Is use of exit status 4 necessary?  Is gropdf already using
> status 3 for something?


The exit status is coming from groff, not gropdf; I presume groff is munging it in some manner as the documentation you quoted implies, although the specific munging does not seem to be exactly in line with that snippet, unless one reads "setting bit 2 if a command exited with a failure status" as also implying "and clearing whatever bits the failing command returned on exit."

Lacking a test-gropdf analogue to the test-groff script, running the latest gropdf directly is not straightforward.

$ echo 'Yo!' | $HOME/groff/build/test-groff -Z -Tpdf | $HOME/groff/build/gropdf
gropdf: fatal error: failed to open 'download' file

There's probably a way to make it work, but it's not worth my time to figure out, since all I care about is "is it 0 or not-0?"

> Conventionally, in groff, we assign exit statuses of low
> value meanings in alignment with common practice.
>
> 0: success
> 1: false; expected failure; unable to perform desired operation
> 2: usage error


That is in line with the documented gropdf exit values quoted in comment #3.

Dave <barx>
Group Member
Wed 22 Oct 2025 07:40:16 PM UTC, comment #7: 


comment #5:

> $ echo 'Yo!' | groff -Tpdf -P--pdfver=1.5 > /dev/null
> gropdf: warning: Only pdf versions 1.4 or 1.7 are supported, not '1.5'
> $ echo $?
> 4


Is use of exit status 4 necessary?  Is gropdf already using status 3 for something?

Conventionally, in groff, we assign exit statuses of low value meanings in alignment with common practice.

0: success
1: false; expected failure; unable to perform desired operation
2: usage error

groff, the program, also relies upon this convention because it assumes the programs it assembles into a pipeline (including output drivers like gropdf) will use at most the two lowest-order bits of the exit status to communicate information.

groff(1):


Exit status
     groff exits successfully (with status 0) if either of the options
     -h or --help is specified, status 2 if the program cannot interpret
     its command‐line arguments, and status 1 if it encounters an error
     during operation.  Otherwise, groff runs a pipeline to process its
     input; if all commands within the pipeline exit successfully, groff
     does likewise.  If not, groff’s exit status encodes a summary of
     problems encountered, setting bit 2 if a command exited with a
     failure status, bit 3 if a command was terminated with a signal,
     and bit 4 if a command could not be executed.  (Thus, if all three
     misfortunes befall one’s pipeline, groff exits with status 2^2 +
     2^3 + 2^4 = 4+8+16 = 28.)  To troubleshoot pipeline problems, re‐
     run the groff command with the -V option and break the reported
     pipeline down into separate stages, inspecting the exit status of,
     and diagnostic messages emitted by, each command.


G. Branden Robinson <gbranden>
Group administrator
Wed 22 Oct 2025 02:48:16 PM UTC, comment #6: 

On Wednesday, 22 October 2025 15:11:23 BST Dave wrote:

> Follow-up Comment #5, bug #67612 (group groff):
>
> Thanks, Deri, for the succinct how-we-got-here.  Might be worth checking
> whether any other messages also got misclassified in the overhaul; this is
> just one I happened across.
>
> I do notice an unexpected result from the test case of bug #67616:
>
> $ groff -Tpdf -P--pdfver=1.5 < /dev/null
> gropdf: warning: Only pdf versions 1.4 or 1.7 are supported, not '1.5'
> $ echo $?
> 0
>
> This is a case of "may fail to render as desired," since gropdf cannot give
> the user what they asked for.  However, that's with a null input, so maybe
> it's OK: the expected nonzero code comes up with even minimal input:
>
> $ echo 'Yo!' | groff -Tpdf -P--pdfver=1.5 > /dev/null
> gropdf: warning: Only pdf versions 1.4 or 1.7 are supported, not '1.5'
> $ echo $?
> 4
>

Yes, I agree, another one to demote to Notice. The pdf produced will perfectly
acceptable, but in 1.7 format. If the user requires the earlier format then
the job can be re-run using 1.4.


Deri James <deri>
Group Member
Wed 22 Oct 2025 02:11:15 PM UTC, comment #5: 

Thanks, Deri, for the succinct how-we-got-here.  Might be worth checking whether any other messages also got misclassified in the overhaul; this is just one I happened across.

I do notice an unexpected result from the test case of bug #67616:

$ groff -Tpdf -P--pdfver=1.5 < /dev/null
gropdf: warning: Only pdf versions 1.4 or 1.7 are supported, not '1.5'
$ echo $?
0

This is a case of "may fail to render as desired," since gropdf cannot give the user what they asked for.  However, that's with a null input, so maybe it's OK: the expected nonzero code comes up with even minimal input:

$ echo 'Yo!' | groff -Tpdf -P--pdfver=1.5 > /dev/null
gropdf: warning: Only pdf versions 1.4 or 1.7 are supported, not '1.5'
$ echo $?
4


Dave <barx>
Group Member
Wed 22 Oct 2025 10:51:14 AM UTC, comment #4: 

Hi Dave,

You are absolutely correct, I have a change in the pipeline to change this message to a Notice. Originally I just had a Msg routine which had a parameter which controlled whether a message was critical (abort) or not. Then Branden added separate Notice/Warn/Die routines as a wrapper. Later, a further refinement needed by Branden was that gropdf exit with a non-zero exit code if any warnings had occurred during a run (to ensure make would abort during a build).

The "speedup" message should have been demoted to a Notice at this point, since it was initially a non-abort Msg. Thanks for catching this over sight.

Deri James <deri>
Group Member
Wed 22 Oct 2025 04:19:16 AM UTC, comment #3: 

The man page text I quoted in comment #1 has been clarified since that commit.  For context, the current text of the whole section is:

Exit status
     0      gropdf successfully produced a PDF document.

     1      gropdf experienced a critical error, or could not interpret its
            arguments.  No PDF was produced, or the document produced will be
            unusable.

     2      gropdf emitted warnings.  The document produced may be usable, but
            may fail to render as desired.

Based on this, I think my conclusion still holds: If something may make a document fail to render as desired, this can reasonably be considered an error, not a warning (but also not a critical error, as defined in the item above).

From code inspection, it looks like the sorts of things that trigger this are the user asking for an unrecognized paper size, an unsupported PDF version, or a nonexistent image file.  Those all fall under "may fail to render as desired," so I don't have a quarrel with considering them errors, and exiting with a nonzero code.

But "You would see a noticeable speedup" falls under the description "successfully produced a PDF document" above, so should exit with 0.  That is, in the parlance of gropdf.pl, this should be a Notice rather than a Warn.

Dave <barx>
Group Member
Mon 20 Oct 2025 09:54:34 PM UTC, comment #2: 


comment #1:

> Ah, the problem isn't tied to this warning in particular.  The commit 6198245ea log says, "src/devices/gropdf/gropdf.pl: Exit with code 2 if any warnings issued during run (this will stop a 'make')."
>
> But it seems to go against the very concept of a warning to stop a build because of one.  "make" builds plenty of code that spits out compiler warnings, and developers would be very cross were that to change: the whole reason something is a warning is so a human can evaluate whether it's an actual problem.  If something rises to the level of "stop 'make'," it should be an error, not a warning.


I concur.  I think a better solution would be for gropdf to support a command-line option or environment variable that caused it to treat warnings as fatal problems.

> This warning in particular doesn't even fit the definition of "warning" that that commit added to the man page: "PDF produced may be usable, but it will have issues."  There seems no way a warning about a slow run time can result in issues in the produced PDF; it just means you wait longer for it.

G. Branden Robinson <gbranden>
Group administrator
Fri 17 Oct 2025 10:26:39 PM UTC, comment #1: 

Ah, the problem isn't tied to this warning in particular.  The commit 6198245ea log says, "src/devices/gropdf/gropdf.pl: Exit with code 2 if any warnings issued during run (this will stop a 'make')."

But it seems to go against the very concept of a warning to stop a build because of one.  "make" builds plenty of code that spits out compiler warnings, and developers would be very cross were that to change: the whole reason something is a warning is so a human can evaluate whether it's an actual problem.  If something rises to the level of "stop 'make'," it should be an error, not a warning.

This warning in particular doesn't even fit the definition of "warning" that that commit added to the man page: "PDF produced may be usable, but it will have issues."  There seems no way a warning about a slow run time can result in issues in the produced PDF; it just means you wait longer for it.

Dave <barx>
Group Member
Fri 17 Oct 2025 06:56:27 PM UTC, original submission:  

This warning was introduced sometime after 1.23.

My system has the Linux Libertine fonts installed under the family name L, but any font family with a large numbers of glyphs should exhibit the problem.

$ printf '.fam L\nHello.\n' | groff -Tpdf > /dev/null
gropdf: warning:
Font 'LinLibertine (LR)' has 2741 glyphs
You would see a noticeable speedup if you install the perl module Inline::C

$ echo $?
4

The PDF produced (even if much more complex than this test case) is flawless, so the exit code should not be one of failure.

Dave <barx>
Group Member

 

Attached Files

This item currently has no attached files.

(Note: upload size limit is set to 4.0MiB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

 

Dependencies

This item does not depend on any other items.

No items depend on this one.

 

Mail Notification Carbon-Copy List

Carbon-Copy List
  • -email is unavailable- added by deri (Posted a comment)
  • -email is unavailable- added by gbranden (Posted a comment)
  • -email is unavailable- added by barx (Submitted the item)
  •  

    Votes

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

    History

    Follow 12 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2025-11-18 gbranden StatusIn Progress Fixed
        Open/ClosedOpen Closed
    2025-11-17 gbranden StatusNeed Info In Progress
        Assigned toderi gbranden
    2025-11-06 gbranden Open/ClosedClosed Open
    2025-11-06 gbranden StatusFixed Need Info
        Summary[gropdf] exits with nonzero status on warning [PATCH] [gropdf] exits with nonzero status on warning
    2025-11-06 gbranden Planned ReleaseNone 1.24.0
    2025-11-04 deri StatusNone Fixed
        Assigned toNone deri
        Open/ClosedOpen Closed
    2025-10-20 gbranden Summarygropdf has nonzero exit on warning [gropdf] exits with nonzero status on warning

    Back to the top

    Powered by Savane 3.16-a7ba.
    Corresponding source code