File: sbuild-ctty.cc

package info (click to toggle)
schroot 1.6.4-4
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 6,684 kB
  • sloc: cpp: 21,427; sh: 12,516; makefile: 829; ansic: 231; sed: 16
file content (130 lines) | stat: -rw-r--r-- 2,977 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* Copyright © 2006-2007  Roger Leigh <rleigh@debian.org>
 *
 * schroot is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * schroot is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 *********************************************************************/

#include <config.h>

#include "sbuild-ctty.h"

#include <cerrno>
#include <cstring>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

using namespace sbuild;

namespace
{

  typedef std::pair<ctty_error_code,const char *> emap;

  /**
   * This is a list of the supported error codes.  It's used to
   * construct the real error codes map.
   */
  emap init_errors[] =
    {
      emap(CTTY_CLOEXEC, N_("The controlling terminal close-on-execute flag could not be set")),
      emap(CTTY_DUP,     N_("The controlling terminal file descriptor could not be duplicated"))
    };

  /**
   * Set close-on-exec flag.  An error will be thrown on failure.
   *
   * @param fd the file descriptor to set.
   */
  void
  set_cloexec (int fd)
  {
    int flags = fcntl(fd, F_GETFD);
    flags |= FD_CLOEXEC;
    if (fcntl(fd, F_SETFD, flags) < 0)
      throw ctty_error(CTTY_CLOEXEC, strerror(errno));
  }

  /**
   * Open the controlling terminal and return its file descriptor.
   *
   * @returns the CTTY fd, or -1 on failure.
   */
  int
  open_ctty ()
  {
    int ctty = open("/dev/tty", O_RDWR|O_NOCTTY);
    if (ctty >= 0)
      {
	set_cloexec(ctty);
      }
    else
      {
	ctty = -1;
      }

    return ctty;
  }

}

template<>
error<ctty_error_code>::map_type
error<ctty_error_code>::error_strings
(init_errors,
 init_errors + (sizeof(init_errors) / sizeof(init_errors[0])));

const int sbuild::CTTY_FILENO(open_ctty());

namespace
{

  /**
   * Get the file descriptor for cttybuf.  An error will be thrown on
   * failure.
   *
   * @returns the CTTY_FILENO file descriptor if there is a CTTY, or a
   * duplicated file descriptor for stdin otherwise.
   */
  int
  cttybuf_fd ()
  {
    int ctty = CTTY_FILENO;

    if (ctty < 0)
      {
	ctty = dup(STDIN_FILENO);

	if (ctty < 0)
	  throw ctty_error(CTTY_DUP, strerror(errno));

	set_cloexec(ctty);
      }

    return ctty;
  }

  /// A streambuf for cctty.
  //  boost::iostreams::file_descriptor cttybuf(cttybuf_fd(), close_handle);

}

#ifdef BOOST_IOSTREAMS_CLOSE_HANDLE_OLD
fdstream sbuild::cctty(cttybuf_fd(), true);
#else
fdstream sbuild::cctty(cttybuf_fd(), boost::iostreams::close_handle);
#endif