Skip to content

Commit 6be7e11

Browse files
committed
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. After this commit we use the macros to obtain the status code and also add some logging on failure. For WIN32 we only check if the return value is non-zero, which should solve, #43327
1 parent 9187cae commit 6be7e11

File tree

7 files changed

+106
-8
lines changed

7 files changed

+106
-8
lines changed

ext/standard/mail.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
#include "ext/date/php_date.h"
2626
#include "zend_smart_str.h"
2727

28+
#ifdef HAVE_SYS_WAIT_H
29+
#include <sys/wait.h>
30+
#endif
31+
2832
#ifdef HAVE_SYSEXITS_H
2933
# include <sysexits.h>
3034
#endif
@@ -417,6 +421,7 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co
417421
#endif
418422
FILE *sendmail;
419423
int ret;
424+
int wstatus;
420425
char *sendmail_path = INI_STR("sendmail_path");
421426
char *sendmail_cmd = NULL;
422427
char *mail_log = INI_STR("mail.log");
@@ -557,26 +562,44 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co
557562
fprintf(sendmail, "%s%s", hdr, line_sep);
558563
}
559564
fprintf(sendmail, "%s%s%s", line_sep, message, line_sep);
565+
#ifdef PHP_WIN32
560566
ret = pclose(sendmail);
561-
562567
#if PHP_SIGCHILD
563568
if (sig_handler) {
564569
signal(SIGCHLD, sig_handler);
565570
}
566571
#endif
567-
568-
#ifdef PHP_WIN32
569-
if (ret == -1)
570572
#else
573+
wstatus = pclose(sendmail);
574+
#if PHP_SIGCHILD
575+
if (sig_handler) {
576+
signal(SIGCHLD, sig_handler);
577+
}
578+
#endif
579+
/* Determine the wait(2) exit status */
580+
if (wstatus == -1) {
581+
php_error_docref(NULL, E_WARNING, "Sendmail pclose failed %d (%s)", errno, strerror(errno));
582+
MAIL_RET(0);
583+
} else if (WIFSIGNALED(wstatus)) {
584+
php_error_docref(NULL, E_WARNING, "Sendmail killed by signal %d (%s)", WTERMSIG(wstatus), strsignal(WTERMSIG(wstatus)));
585+
MAIL_RET(0);
586+
} else if (!WIFEXITED(wstatus)) {
587+
php_error_docref(NULL, E_WARNING, "Sendmail did not exit");
588+
MAIL_RET(0);
589+
} else {
590+
ret = WEXITSTATUS(wstatus);
591+
}
592+
#endif
593+
571594
#if defined(EX_TEMPFAIL)
572595
if ((ret != EX_OK)&&(ret != EX_TEMPFAIL))
573596
#elif defined(EX_OK)
574597
if (ret != EX_OK)
575598
#else
576599
if (ret != 0)
577-
#endif
578600
#endif
579601
{
602+
php_error_docref(NULL, E_WARNING, "Sendmail exited with non-zero exit code %d", ret);
580603
MAIL_RET(0);
581604
} else {
582605
MAIL_RET(1);

ext/standard/tests/mail/gh10990.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ $from = '[email protected]';
1313
$headers = ['From' => &$from];
1414
var_dump(mail('[email protected]', 'Test', 'Test', $headers));
1515
?>
16-
--EXPECT--
16+
--EXPECTF--
17+
Warning: mail(): Sendmail exited with non-zero exit code 127 in %sgh10990.php on line %d
1718
bool(false)

ext/standard/tests/mail/mail_basic5.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ $message = 'A Message';
2020
echo "-- failure --\n";
2121
var_dump( mail($to, $subject, $message) );
2222
?>
23-
--EXPECT--
23+
--EXPECTF--
2424
*** Testing mail() : basic functionality ***
2525
-- failure --
26+
27+
Warning: mail(): Sendmail exited with non-zero exit code 1 in %smail_basic5.php on line %d
2628
bool(false)

ext/standard/tests/mail/mail_variation1.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ $subject = 'Test Subject';
1717
$message = 'A Message';
1818
var_dump( mail($to, $subject, $message) );
1919
?>
20-
--EXPECT--
20+
--EXPECTF--
2121
*** Testing mail() : variation ***
22+
23+
Warning: mail(): Sendmail exited with non-zero exit code 127 in %smail_variation1.php on line %d
2224
bool(false)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Test mail() function : variation sendmail temp fail
3+
--INI--
4+
sendmail_path=exit 75
5+
--SKIPIF--
6+
<?php
7+
if(substr(PHP_OS, 0, 3) == "WIN")
8+
die("skip Won't run on Windows");
9+
?>
10+
--FILE--
11+
<?php
12+
echo "*** Testing mail() : variation ***\n";
13+
14+
// Initialise all required variables
15+
16+
$subject = 'Test Subject';
17+
$message = 'A Message';
18+
var_dump( mail($to, $subject, $message) );
19+
?>
20+
--EXPECT--
21+
*** Testing mail() : variation ***
22+
bool(true)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Test mail() function : variation sigkill
3+
--INI--
4+
sendmail_path="kill \$\$"
5+
--SKIPIF--
6+
<?php
7+
if(substr(PHP_OS, 0, 3) == "WIN")
8+
die("skip Won't run on Windows");
9+
?>
10+
--FILE--
11+
<?php
12+
echo "*** Testing mail() : variation ***\n";
13+
14+
// Initialise all required variables
15+
16+
$subject = 'Test Subject';
17+
$message = 'A Message';
18+
var_dump( mail($to, $subject, $message) );
19+
?>
20+
--EXPECTF--
21+
*** Testing mail() : variation ***
22+
23+
Warning: mail(): Sendmail killed by signal %d (%s) in %smail_variation4.php on line %d
24+
bool(false)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Test mail() function : variation non-zero exit
3+
--INI--
4+
sendmail_path="exit 123"
5+
--SKIPIF--
6+
<?php
7+
if(substr(PHP_OS, 0, 3) == "WIN")
8+
die("skip Won't run on Windows");
9+
?>
10+
--FILE--
11+
<?php
12+
echo "*** Testing mail() : variation ***\n";
13+
14+
// Initialise all required variables
15+
16+
$subject = 'Test Subject';
17+
$message = 'A Message';
18+
var_dump( mail($to, $subject, $message) );
19+
?>
20+
--EXPECTF--
21+
*** Testing mail() : variation ***
22+
23+
Warning: mail(): Sendmail exited with non-zero exit code 123 in %smail_variation5.php on line %d
24+
bool(false)

0 commit comments

Comments
 (0)