2 * sysstat test functions.
3 * (C) 2019-2022 by Sebastien GODARD (sysstat <at> orange.fr)
5 ***************************************************************************
6 * This program is free software; you can redistribute it and/or modify it *
7 * under the terms of the GNU General Public License as published by the *
8 * Free Software Foundation; either version 2 of the License, or (at your *
9 * option) any later version. *
11 * This program is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY *
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
16 * You should have received a copy of the GNU General Public License along *
17 * with this program; if not, write to the Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA *
19 ***************************************************************************
33 #include <sys/utsname.h>
34 #include <sys/statvfs.h>
36 #include <sys/types.h>
40 time_t __unix_time = 0;
44 extern int sigint_caught;
47 ***************************************************************************
48 * Test mode: Instead of reading system time, use time given on the command
52 * Number of seconds since the epoch, as given on the command line.
53 ***************************************************************************
55 time_t get_unix_time(time_t *t)
61 ***************************************************************************
62 * Test mode: Get time of the day using __unix_time variable contents.
65 * @tv Number of seconds since the Epoch.
66 ***************************************************************************
68 void get_day_time(struct timeval *tv)
70 __unix_time += interval;
71 tv->tv_sec = __unix_time;
76 ***************************************************************************
77 * Test mode: Send bogus information about current kernel.
80 * @h Structure with kernel information.
81 ***************************************************************************
83 void get_uname(struct utsname *h)
85 strcpy(h->sysname, "Linux");
86 strcpy(h->nodename, "SYSSTAT.TEST");
87 strcpy(h->release, "1.2.3-TEST");
88 strcpy(h->machine, "x86_64");
92 ***************************************************************************
93 * Test mode: Send bogus information about current filesystem.
96 * @buf Structure with filesystem information.
97 ***************************************************************************
99 int get_fs_stat(char *c, struct statvfs *buf)
103 * f_bfree, f_blocks and f_bavail used to be unsigned long.
104 * So don't use values greater then UINT_MAX to make sure that values
105 * won't overflow on 32-bit systems.
107 unsigned long long bfree[4] = {739427840, 286670336, 1696156672, 2616732672};
108 unsigned long long blocks[4] = {891291136, 502345216, 1829043712, 3502345216};
109 unsigned long long bavail[4] = {722675712, 241253120, 1106515456, 1871315456};
110 unsigned long long files[4] = {6111232, 19202048, 1921360, 19202048};
111 unsigned long long ffree[4] = {6008414, 19201593, 1621550, 19051710};
113 buf->f_bfree = bfree[p];
114 buf->f_blocks = blocks[p];
115 buf->f_bavail = bavail[p];
117 buf->f_files = files[p];
118 buf->f_ffree = ffree[p];
126 ***************************************************************************
127 * Test mode: Ignore environment variable value.
128 ***************************************************************************
130 char *get_env_value(const char *c)
135 fprintf(stderr, "Reading contents of %s\n", c);
140 ***************************************************************************
141 * Test mode: Go to next time period.
142 ***************************************************************************
144 void next_time_step(void)
147 char rootf[64], testf[128];
150 __unix_time += interval;
152 /* Get root directory name (root1, root2, etc.) at which the "root" symlink points */
153 if ((resolved_name = realpath(ROOTDIR, NULL)) != NULL) {
154 if (strlen(resolved_name) > 4) {
155 /* Set root_nr to the root directory number (1, 2, etc.) */
156 root_nr = atoi(resolved_name + strlen(resolved_name) - 1);
160 if ((unlink(ROOTDIR) < 0) && (errno != ENOENT)) {
165 /* Set next root directory name (root2, root3, etc.). Directories like root1b are unreachable */
166 snprintf(rootf, sizeof(rootf), "%s%d", ROOTFILE, ++root_nr);
167 rootf[sizeof(rootf) - 1] = '\0';
168 snprintf(testf, sizeof(testf), "%s/%s", TESTDIR, rootf);
169 testf[sizeof(testf) - 1] = '\0';
171 /* Make sure that new root directory exists */
172 if (access(testf, F_OK) < 0) {
173 if (errno == ENOENT) {
174 /* No more root directories: Simulate a Ctrl/C */
180 /* Create "root" symlink pointing at the new root directory */
181 if (symlink(rootf, ROOTDIR) < 0) {
188 ***************************************************************************
189 * If current file is considered as a virtual one ("virtualhd"), then set
190 * its device ID (major 253, minor 2, corresponding here to dm-2) in the
191 * stat structure normally filled by the stat() system call.
192 * Otherwise, open file and read its major and minor numbers.
195 * @name Pathname to file.
198 * @statbuf Structure containing device ID.
201 * 0 if it actually was the virtual device, 1 otherwise, and -1 on failure.
202 ***************************************************************************
204 int virtual_stat(const char *name, struct stat *statbuf)
210 if (!strcmp(name, VIRTUALHD)) {
211 statbuf->st_rdev = (253 << MINORBITS) + 2;
215 statbuf->st_rdev = 0;
217 if ((fp = fopen(name, "r")) == NULL)
220 if (fgets(line, sizeof(line), fp) != NULL) {
221 sscanf(line, "%d %d", &major, &minor);
222 statbuf->st_rdev = (major << MINORBITS) + minor;
231 ***************************************************************************
232 * Open a "_list" file containing a list of files enumerated in a known
233 * order contained in current directory.
236 * @name Pathname to directory containing the "_list" file.
239 * A pointer on current "_list" file.
240 ***************************************************************************
242 DIR *open_list(const char *name)
247 snprintf(filename, sizeof(filename), "%s/%s", name, _LIST);
248 filename[sizeof(filename) - 1] = '\0';
250 if ((fp = fopen(filename, "r")) == NULL)
257 ***************************************************************************
258 * Read next file name contained in a "_list" file.
261 * @dir Pointer on current "_list" file.
264 * A structure containing the name of the next file to read.
265 ***************************************************************************
267 struct dirent *read_list(DIR *dir)
269 FILE *fp = (FILE *) dir;
270 static struct dirent drd;
274 if ((fgets(line, sizeof(line), fp) != NULL) && (strlen(line) > 1) &&
275 (strlen(line) < sizeof(drd.d_name))) {
276 strcpy(drd.d_name, line);
277 drd.d_name[strlen(line) - 1] = '\0';
285 ***************************************************************************
286 * Close a "_list" file.
289 * @dir Pointer on "_list" file to close.
290 ***************************************************************************
292 void close_list(DIR *dir)
294 FILE *fp = (FILE *) dir;
300 ***************************************************************************
301 * Replacement function for realpath() system call. Do nothing here.
304 * @name Pathname to process.
308 * Pathname (unchanged).
309 ***************************************************************************
311 char *get_realname(char *name, char *c)
315 if ((resolved_name = (char *) malloc(1024)) == NULL) {
319 strncpy(resolved_name, name, 1024);
320 resolved_name[1023] = '\0';
322 return resolved_name;
326 ***************************************************************************
327 * Replacement function for getpwuid() system call. Fill a dummy passwd
328 * structure containing the name of a user.
331 * @uid UID of the user
334 * Pointer on the passwd structure.
335 ***************************************************************************
337 struct passwd *get_usrname(uid_t uid)
339 static struct passwd pwd_ent;
340 static char pw_name[16];
342 pwd_ent.pw_name = pw_name;
344 strcpy(pwd_ent.pw_name, "root");
347 strcpy(pwd_ent.pw_name, "testusr");
354 ***************************************************************************
355 * Replacement function for fork() system call. Don't fork really but return
356 * a known PID number.
360 ***************************************************************************
362 pid_t get_known_pid(void)