79659664409ce35edfe2964ae19188f307775084
[m6w6/libmemcached] / libtest / wait.cc
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * libtest
4 *
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 3 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <config.h>
23
24 #include <cstdlib>
25 #include <fcntl.h>
26 #include <getopt.h>
27 #include <iostream>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31
32 #include <libtest/wait.h>
33
34 static void version_command(const char *command_name, int major_version, int minor_version)
35 {
36 std::cout << command_name << " " << major_version << "." << minor_version << std::endl;
37 }
38
39 static void help_command(const char *command_name,
40 int major_version, int minor_version,
41 const struct option *long_options)
42 {
43 std::cout << command_name << " " << major_version << "." << minor_version << std::endl;
44 std::cout << "Current options. A '=' means the option takes a value." << std::endl << std::endl;
45
46 for (uint32_t x= 0; long_options[x].name; x++)
47 {
48 std::cout << "\t --" << long_options[x].name << char(long_options[x].has_arg ? '=' : ' ') << std::endl;
49 }
50
51 std::cout << std::endl;
52 }
53
54 static void close_stdio(void)
55 {
56 int fd;
57 if ((fd = open("/dev/null", O_RDWR, 0)) < 0)
58 {
59 return;
60 }
61 else
62 {
63 if (dup2(fd, STDIN_FILENO) < 0)
64 {
65 return;
66 }
67
68 if (dup2(fd, STDOUT_FILENO) < 0)
69 {
70 return;
71 }
72
73 if (dup2(fd, STDERR_FILENO) < 0)
74 {
75 return;
76 }
77
78 if (fd > STDERR_FILENO)
79 {
80 close(fd);
81 }
82 }
83 }
84
85 enum {
86 OPT_HELP,
87 OPT_QUIET,
88 OPT_VERSION
89 };
90
91 static void options_parse(int argc, char *argv[])
92 {
93 static struct option long_options[]=
94 {
95 { "version", no_argument, NULL, OPT_VERSION},
96 { "help", no_argument, NULL, OPT_HELP},
97 { "quiet", no_argument, NULL, OPT_QUIET},
98 {0, 0, 0, 0},
99 };
100
101 bool opt_version= false;
102 bool opt_help= false;
103 bool opt_quiet= false;
104 int option_index= 0;
105
106 while (1)
107 {
108 int option_rv= getopt_long(argc, argv, "", long_options, &option_index);
109 if (option_rv == -1)
110 {
111 break;
112 }
113
114 switch (option_rv)
115 {
116 case OPT_HELP: /* --help or -h */
117 opt_help= true;
118 break;
119
120 case OPT_VERSION: /* --version or -v */
121 opt_version= true;
122 break;
123
124 case OPT_QUIET:
125 opt_quiet= true;
126 break;
127
128 case '?':
129 /* getopt_long already printed an error message. */
130 exit(EXIT_FAILURE);
131
132 default:
133 help_command(argv[0], 1, 0, long_options);
134 exit(EXIT_FAILURE);
135 }
136 }
137
138 if (opt_quiet)
139 {
140 close_stdio();
141 }
142
143 if (opt_version)
144 {
145 version_command(argv[0], 1, 0);
146 exit(EXIT_SUCCESS);
147 }
148
149 if (opt_help)
150 {
151 help_command(argv[0], 1, 0, long_options);
152 exit(EXIT_SUCCESS);
153 }
154 }
155
156 int main(int argc, char *argv[])
157 {
158 if (argc == 1)
159 {
160 return EXIT_FAILURE;
161 }
162
163 options_parse(argc, argv);
164
165 int ret= EXIT_FAILURE;
166 while (optind < argc)
167 {
168 libtest::Wait wait(argv[optind++]);
169
170 if (wait.successful() == false)
171 {
172 return EXIT_FAILURE;
173 }
174
175 ret= EXIT_SUCCESS;
176 }
177
178 return ret;
179 }