Page MenuHomePhabricator

0048-mail-fix-exit-code-handling-of-sendmail-cmd.patch

Authored By
Scott_French
Aug 5 2025, 9:28 PM
Size
3 KB
Referenced Files
None
Subscribers
None

0048-mail-fix-exit-code-handling-of-sendmail-cmd.patch

Backport of upstream commit c5e7490
mail: fix exit code handling of sendmail cmd
Prior to this commit the return code of the pclose function was assumed
to be the exit code of the process. However, the returned value as
specified in wait(2) is a bit packed integer and must be interpreted
with the provided macros. This has no effect in success cases as the
integer is still zero, but in failure cases the wrong value is used,
since the 8 least significant bits contain the status code. After this
commit we use the macros to obtain the status code, which fixes the
EX_TEMPFAIL conditional.
For WIN32 the TSRM popen_ex and pclose function are used. The return
value of TSRM's pclose is not bit packed so we only check if the return
value is non-zero, which should solve, #43327,
https://bugs.php.net/bug.php?id=43327
--- a/ext/standard/mail.c
+++ b/ext/standard/mail.c
@@ -25,6 +25,10 @@
#include "ext/date/php_date.h"
#include "zend_smart_str.h"
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
#if HAVE_SYSEXITS_H
#include <sysexits.h>
#endif
@@ -518,6 +522,7 @@
fprintf(sendmail, "%s\r\n", hdr);
}
fprintf(sendmail, "\r\n%s\r\n", message);
+#ifdef PHP_WIN32
ret = pclose(sendmail);
#if PHP_SIGCHILD
@@ -525,10 +530,27 @@
signal(SIGCHLD, sig_handler);
}
#endif
-
-#ifdef PHP_WIN32
- if (ret == -1)
#else
+ int wstatus = pclose(sendmail);
+#if PHP_SIGCHILD
+ if (sig_handler) {
+ signal(SIGCHLD, sig_handler);
+ }
+#endif
+ /* Determine the wait(2) exit status */
+ if (wstatus == -1) {
+ MAIL_RET(0);
+ } else if (WIFSIGNALED(wstatus)) {
+ MAIL_RET(0);
+ } else {
+ if (WIFEXITED(wstatus)) {
+ ret = WEXITSTATUS(wstatus);
+ } else {
+ MAIL_RET(0);
+ }
+ }
+#endif
+
#if defined(EX_TEMPFAIL)
if ((ret != EX_OK)&&(ret != EX_TEMPFAIL))
#elif defined(EX_OK)
@@ -536,7 +558,6 @@
#else
if (ret != 0)
#endif
-#endif
{
MAIL_RET(0);
} else {
--- /dev/null
+++ b/ext/standard/tests/mail/mail_variation3.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test mail() function : variation sendmail temp fail
+--INI--
+sendmail_path=exit 75
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == "WIN")
+ die("skip Won't run on Windows");
+?>
+--FILE--
+<?php
+echo "*** Testing mail() : variation ***\n";
+
+// Initialise all required variables
+$to = 'user@example.com';
+$subject = 'Test Subject';
+$message = 'A Message';
+var_dump(mail($to, $subject, $message));
+?>
+--EXPECT--
+*** Testing mail() : variation ***
+bool(true)
--- /dev/null
+++ b/ext/standard/tests/mail/mail_variation4.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test mail() function : variation sigterm
+--INI--
+sendmail_path="kill \$\$"
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == "WIN")
+ die("skip Won't run on Windows");
+?>
+--FILE--
+<?php
+echo "*** Testing mail() : variation ***\n";
+
+// Initialise all required variables
+$to = 'user@example.com';
+$subject = 'Test Subject';
+$message = 'A Message';
+var_dump(mail($to, $subject, $message));
+?>
+--EXPECT--
+*** Testing mail() : variation ***
+bool(false)
--- /dev/null
+++ b/ext/standard/tests/mail/mail_variation5.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test mail() function : variation non-zero exit
+--INI--
+sendmail_path="exit 123"
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == "WIN")
+ die("skip Won't run on Windows");
+?>
+--FILE--
+<?php
+echo "*** Testing mail() : variation ***\n";
+
+// Initialise all required variables
+$to = 'user@example.com';
+$subject = 'Test Subject';
+$message = 'A Message';
+var_dump(mail($to, $subject, $message));
+?>
+--EXPECT--
+*** Testing mail() : variation ***
+bool(false)

File Metadata

Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
21635646
Default Alt Text
0048-mail-fix-exit-code-handling-of-sendmail-cmd.patch (3 KB)

Event Timeline