Remove the run file if the build fails.
[util-vserver.git] / src / vmemctrl.c
1 // $Id$
2
3 // Copyright (C) 2007 Daniel Hokka Zakrisson
4 //  
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or (at your option)
8 // any later version.
9 //  
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //  
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include "vserver.h"
24 #include "util.h"
25
26 #include <lib/internal.h>
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <errno.h>
33 #include <getopt.h>
34
35 #define ENSC_WRAPPERS_PREFIX    "vmemctrl: "
36 #define ENSC_WRAPPERS_VSERVER   1
37 #define ENSC_WRAPPERS_UNISTD    1
38 #include "wrappers.h"
39
40 #define CMD_HELP        0x1000
41 #define CMD_VERSION     0x1001
42
43 #define CMD_SET         0x2000
44 #define CMD_GET         0x2001
45
46 #define CMD_XID         0x4000
47 #define CMD_BADNESS     0x4001
48
49 int wrapper_exit_code = 255;
50
51
52 static struct option const
53 CMDLINE_OPTIONS[] = {
54   { "help",     no_argument,        0, CMD_HELP },
55   { "version",  no_argument,        0, CMD_VERSION },
56   { "set",      no_argument,        0, CMD_SET },
57   { "get",      no_argument,        0, CMD_GET },
58   { "xid",      required_argument,  0, CMD_XID },
59   { "badness",  required_argument,  0, CMD_BADNESS },
60   { 0,0,0,0 }
61 };
62
63 struct Arguments {
64   xid_t         xid;
65   int64_t       badness;
66   bool          do_set;
67   bool          do_get;
68   uint32_t      mask;
69 };
70
71 static inline int
72 hasArg(struct Arguments *args, uint32_t arg)
73 {
74   return (args->mask & arg) == arg;
75 }
76
77 static void
78 showHelp(int fd, char const *cmd, int res)
79 {
80   WRITE_MSG(fd, "Usage:\n  ");
81   WRITE_STR(fd, cmd);
82   WRITE_MSG(fd,
83             " (--set|--get) [--xid <xid>] [--badness <OOM bias>]\n"
84             "        [--] [<command> <args>*]\n\n"
85             "Please report bugs to " PACKAGE_BUGREPORT "\n");
86
87   exit(res);
88 }
89
90 static void
91 showVersion()
92 {
93   WRITE_MSG(1,
94             "vmemctrl " VERSION " -- \n"
95             "This program is part of " PACKAGE_STRING "\n\n"
96             "Copyright (C) 2007 Daniel Hokka Zakrisson\n"
97             VERSION_COPYRIGHT_DISCLAIMER);
98   exit(0);
99 }
100
101 static inline void
102 doset(struct Arguments *args)
103 {
104   if (hasArg(args, CMD_BADNESS) &&
105       vc_set_badness(args->xid, args->badness) == -1) {
106     perror(ENSC_WRAPPERS_PREFIX "vc_set_badness()");
107     exit(wrapper_exit_code);
108   }
109 }
110
111 static inline void
112 doget(struct Arguments *args)
113 {
114   int64_t badness;
115   char buf[32];
116   size_t l;
117   if (vc_get_badness(args->xid, &badness) == -1) {
118     perror(ENSC_WRAPPERS_PREFIX "vc_get_badness()");
119     exit(wrapper_exit_code);
120   }
121   l = utilvserver_fmt_int64(buf, badness);
122   buf[l] = '\0';
123   WRITE_STR(1, buf);
124   WRITE_MSG(1, "\n");
125 }
126
127 int main (int argc, char *argv[])
128 {
129   struct Arguments args = {
130     .do_set     = false,
131     .do_get     = false,
132     .xid        = VC_NOCTX,
133     .badness    = 0,
134     .mask       = 0,
135   };
136   
137   while (1) {
138     int         c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
139     if (c==-1) break;
140
141     switch (c) {
142       case CMD_HELP     :  showHelp(1, argv[0], 0);
143       case CMD_VERSION  :  showVersion();
144       case CMD_XID      :  args.xid       = Evc_xidopt2xid(optarg,true); break;
145       case CMD_SET      :  args.do_set    = true; break;
146       case CMD_GET      :  args.do_get    = true; break;
147       case CMD_BADNESS  : {
148         char *endptr;
149         args.badness = strtoll(optarg, &endptr, 0);
150         if (*endptr) {
151           WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "Badness '");
152           WRITE_STR(2, optarg);
153           WRITE_MSG(2, "' is not an integer\n");
154           exit(wrapper_exit_code);
155         }
156         break;
157       }
158       default           :
159         WRITE_MSG(2, "Try '");
160         WRITE_STR(2, argv[0]);
161         WRITE_MSG(2, " --help' for more information.\n");
162         exit(wrapper_exit_code);
163         break;
164     }
165     args.mask |= c;
166   }
167
168   if (args.xid == VC_NOCTX) args.xid = Evc_get_task_xid(0);
169
170   if (!args.do_set && !args.do_get) {
171     WRITE_MSG(2, "No operation specified; try '--help' for more information\n");
172     exit(wrapper_exit_code);
173   }
174   else if (((args.do_set ? 1 : 0) + (args.do_get ? 1 : 0)) > 1) {
175     WRITE_MSG(2, "Multiple operations specified; try '--help' for more information\n");
176     exit(wrapper_exit_code);
177   }
178
179   if (args.do_set)
180     doset(&args);
181   else if (args.do_get)
182     doget(&args);
183
184   if (optind != argc)
185     Eexecvp (argv[optind],argv+optind);
186   return EXIT_SUCCESS;
187 }