Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Mar 1999 00:13:09 +0100
From:      Ollivier Robert <roberto@keltia.freenix.fr>
To:        "FreeBSD Hackers' list" <freebsd-hackers@FreeBSD.ORG>
Subject:   Fwd: Re: cron problem?
Message-ID:  <19990322001309.A53335@keltia.freenix.fr>

next in thread | raw e-mail | index | archive | help
Wietse found the following while writing Postfix. Can anyone look at it ?

----- Forwarded message from Wietse Venema <wietse@porcupine.org> -----

Subject: Re: cron problem?
Date: Fri, 19 Mar 1999 14:59:34 -0500 (EST)
From: wietse@porcupine.org (Wietse Venema)

Found it. I'll post a patch later. This must be a *BSD oddity.

	Wietse

Problem: 

	Vixie cron output from an /etc/crontab entry is not mailed,
	unless the crontab line ends with an explicit mail command

System:

	FreeBSD 2.x, BSD/OS 2.x ... (yes I'm not running the latest)

Analysis:

	For the sake of security and robustness, Postfix tries to
	ensure that stdin/out/err are open before opening anything
	else.  The following code fragment appears in many programs
	that I wrote in the course of time:

	    for (fd = 0; fd < 3; fd++)
		if (fstat(fd, &st) == -1 && open("/dev/null", O_WRONLY) != fd)
		    msg_fatal("open /dev/null: %m");

	This fragment examines the status of stdin/stdout/stderr.
	When fstat() returns an error, the code assumes the file
	descriptor is not in use, and expects that the next open()
	will allocate that file descriptor.

	However, the kernel trace shows a small surprise:

	  3817 sendmail CALL  fstat(0,0xefbfddc8)
	  3817 sendmail RET   fstat 0
	  3817 sendmail CALL  fstat(0x1,0xefbfddc8)
	  3817 sendmail RET   fstat -1 errno 9 Bad file descriptor
	  3817 sendmail CALL  open(0x1c8c,0x1,0xefbfde4c)
	  3817 sendmail NAMI  "/dev/null"
	  3817 sendmail RET   open 3

	So: fstat(1) returns EBADF, and open() returns 3.

	Conclusion: file descriptor 1 is still in use.

	*** Why on earth does fstat() return EBADF on an open file
	descriptor? ***

Workaround:

	Close the file descriptor after error return from fstat().

	The following code does the job.

	    if (fstat(fd, &st) == -1
		&& (close(fd), open("/dev/null", O_WRONLY)) != fd)
		msg_fatal("open /dev/null: %m");




----- End forwarded message -----

-- 
Ollivier ROBERT -=- FreeBSD: The Power to Serve! -=- roberto@keltia.freenix.fr
FreeBSD keltia.freenix.fr 4.0-CURRENT #70: Sat Feb 27 09:43:08 CET 1999



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990322001309.A53335>