]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/tools/lxc_console.c
fd: only add valid fd to mainloop
[mirror_lxc.git] / src / lxc / tools / lxc_console.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef _GNU_SOURCE
25 #define _GNU_SOURCE 1
26 #endif
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <libgen.h>
30 #include <poll.h>
31 #include <signal.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sys/ioctl.h>
36 #include <sys/param.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <unistd.h>
40
41 #include <lxc/lxccontainer.h>
42
43 #include "arguments.h"
44 #include "config.h"
45 #include "log.h"
46 #include "utils.h"
47
48 lxc_log_define(lxc_console, lxc);
49
50 static int my_parser(struct lxc_arguments *args, int c, char *arg);
51 static char etoc(const char *expr);
52
53 static const struct option my_longopts[] = {
54 {"tty", required_argument, 0, 't'},
55 {"escape", required_argument, 0, 'e'},
56 LXC_COMMON_OPTIONS
57 };
58
59 static struct lxc_arguments my_args = {
60 .progname = "lxc-console",
61 .help = "\
62 --name=NAME [--tty NUMBER]\n\
63 \n\
64 lxc-console logs on the container with the identifier NAME\n\
65 \n\
66 Options :\n\
67 -n, --name=NAME NAME of the container\n\
68 -t, --tty=NUMBER console tty number\n\
69 -e, --escape=PREFIX prefix for escape command\n\
70 --rcfile=FILE Load configuration file FILE\n",
71 .options = my_longopts,
72 .parser = my_parser,
73 .checker = NULL,
74 .log_priority = "ERROR",
75 .log_file = "none",
76 .ttynum = -1,
77 .escape = 1,
78 };
79
80 static int my_parser(struct lxc_arguments *args, int c, char *arg)
81 {
82 switch (c) {
83 case 't':
84 if (lxc_safe_uint(arg, &args->ttynum) < 0)
85 return -1;
86 break;
87 case 'e':
88 args->escape = etoc(arg);
89 break;
90 }
91
92 return 0;
93 }
94
95 static char etoc(const char *expr)
96 {
97 /* returns "control code" of given expression */
98 char c = expr[0] == '^' ? expr[1] : expr[0];
99
100 return 1 + ((c > 'Z') ? (c - 'a') : (c - 'Z'));
101 }
102
103 int main(int argc, char *argv[])
104 {
105 int ret;
106 struct lxc_container *c;
107 struct lxc_log log;
108
109 if (lxc_arguments_parse(&my_args, argc, argv))
110 exit(EXIT_FAILURE);
111
112 log.name = my_args.name;
113 log.file = my_args.log_file;
114 log.level = my_args.log_priority;
115 log.prefix = my_args.progname;
116 log.quiet = my_args.quiet;
117 log.lxcpath = my_args.lxcpath[0];
118
119 if (lxc_log_init(&log))
120 exit(EXIT_FAILURE);
121
122 c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
123 if (!c) {
124 ERROR("System error loading container");
125 exit(EXIT_FAILURE);
126 }
127
128 if (my_args.rcfile) {
129 c->clear_config(c);
130
131 if (!c->load_config(c, my_args.rcfile)) {
132 ERROR("Failed to load rcfile");
133 lxc_container_put(c);
134 exit(EXIT_FAILURE);
135 }
136
137 c->configfile = strdup(my_args.rcfile);
138 if (!c->configfile) {
139 ERROR("Out of memory setting new config filename");
140 lxc_container_put(c);
141 exit(EXIT_FAILURE);
142 }
143 }
144
145 if (!c->may_control(c)) {
146 ERROR("Insufficent privileges to control %s", my_args.name);
147 lxc_container_put(c);
148 exit(EXIT_FAILURE);
149 }
150
151 if (!c->is_running(c)) {
152 ERROR("%s is not running", my_args.name);
153 lxc_container_put(c);
154 exit(EXIT_FAILURE);
155 }
156
157 ret = c->console(c, my_args.ttynum, 0, 1, 2, my_args.escape);
158 if (ret < 0) {
159 lxc_container_put(c);
160 exit(EXIT_FAILURE);
161 }
162
163 lxc_container_put(c);
164 exit(EXIT_SUCCESS);
165 }