12940b44dSPeter Avalos ///////////////////////////////////////////////////////////////////////////////
22940b44dSPeter Avalos //
32940b44dSPeter Avalos /// \file       tuklib_open_stdxxx.c
42940b44dSPeter Avalos /// \brief      Make sure that file descriptors 0, 1, and 2 are open
52940b44dSPeter Avalos //
62940b44dSPeter Avalos //  Author:     Lasse Collin
72940b44dSPeter Avalos //
82940b44dSPeter Avalos //  This file has been put into the public domain.
92940b44dSPeter Avalos //  You can do whatever you want with this file.
102940b44dSPeter Avalos //
112940b44dSPeter Avalos ///////////////////////////////////////////////////////////////////////////////
122940b44dSPeter Avalos 
132940b44dSPeter Avalos #include "tuklib_open_stdxxx.h"
142940b44dSPeter Avalos 
152940b44dSPeter Avalos #ifndef TUKLIB_DOSLIKE
162940b44dSPeter Avalos #	include <stdlib.h>
172940b44dSPeter Avalos #	include <errno.h>
182940b44dSPeter Avalos #	include <fcntl.h>
192940b44dSPeter Avalos #	include <unistd.h>
202940b44dSPeter Avalos #endif
212940b44dSPeter Avalos 
222940b44dSPeter Avalos 
232940b44dSPeter Avalos extern void
tuklib_open_stdxxx(int err_status)242940b44dSPeter Avalos tuklib_open_stdxxx(int err_status)
252940b44dSPeter Avalos {
262940b44dSPeter Avalos #ifdef TUKLIB_DOSLIKE
272940b44dSPeter Avalos 	// Do nothing, just silence warnings.
282940b44dSPeter Avalos 	(void)err_status;
292940b44dSPeter Avalos 
302940b44dSPeter Avalos #else
312940b44dSPeter Avalos 	for (int i = 0; i <= 2; ++i) {
322940b44dSPeter Avalos 		// We use fcntl() to check if the file descriptor is open.
332940b44dSPeter Avalos 		if (fcntl(i, F_GETFD) == -1 && errno == EBADF) {
342940b44dSPeter Avalos 			// With stdin, we could use /dev/full so that
352940b44dSPeter Avalos 			// writing to stdin would fail. However, /dev/full
362940b44dSPeter Avalos 			// is Linux specific, and if the program tries to
372940b44dSPeter Avalos 			// write to stdin, there's already a problem anyway.
382940b44dSPeter Avalos 			const int fd = open("/dev/null", O_NOCTTY
392940b44dSPeter Avalos 					| (i == 0 ? O_WRONLY : O_RDONLY));
402940b44dSPeter Avalos 
412940b44dSPeter Avalos 			if (fd != i) {
42*b892b6baSPeter Avalos 				if (fd != -1)
43*b892b6baSPeter Avalos 					(void)close(fd);
44*b892b6baSPeter Avalos 
452940b44dSPeter Avalos 				// Something went wrong. Exit with the
462940b44dSPeter Avalos 				// exit status we were given. Don't try
472940b44dSPeter Avalos 				// to print an error message, since stderr
482940b44dSPeter Avalos 				// may very well be non-existent. This
492940b44dSPeter Avalos 				// error should be extremely rare.
502940b44dSPeter Avalos 				exit(err_status);
512940b44dSPeter Avalos 			}
522940b44dSPeter Avalos 		}
532940b44dSPeter Avalos 	}
542940b44dSPeter Avalos #endif
552940b44dSPeter Avalos 
562940b44dSPeter Avalos 	return;
572940b44dSPeter Avalos }
58