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