27#elif defined(HAVE_UTIL_H)
29#elif defined(HAVE_LIBUTIL_H)
34#include <sys/termios.h>
40 const char *target_name,
41 exe_disk_file_t *dfile,
43static void check_file(
int index, exe_disk_file_t *dfile);
50 exe_disk_file_t *dfile,
53 struct stat64 *s = dfile->stat;
56 if (snprintf(buf,
sizeof buf,
"%s.lnk", fname) >= PATH_MAX) {
57 fputs(
"create_link: fname is too long for additional .lnk suffix", stderr);
61 s->st_mode = (s->st_mode & ~S_IFMT) | S_IFREG;
64 int res = symlink(buf, fname);
69 return open(fname, O_RDWR);
73static int create_dir(
const char *fname, exe_disk_file_t *dfile,
75 int res = mkdir(fname, dfile->stat->st_mode);
80 return open(fname, O_RDWR);
85 gettimeofday(&t, NULL);
87 return (
double) t.tv_sec + ((double) t.tv_usec / 1000000.0);
92 char *t = getenv(
"KLEE_REPLAY_TIMEOUT");
93 int timeout = t ? atoi(t) : 5;
94 double wait = timeout * .5;
96 fprintf(stderr,
"KLEE-REPLAY: NOTE: %s: waiting %.2fs\n", name, wait);
97 while (
getTime() - start < wait) {
98 struct timespec r = {0, 1000000};
100 int res = waitpid(pid, statusp, WNOHANG);
109 const char *tmpdir) {
110 struct stat64 *s = dfile->stat;
111 unsigned flen = dfile->size;
112 char* contents = dfile->contents;
115 struct termios term, *ts=&term;
116 struct winsize win = { 24, 80, 0, 0 };
126 ts->c_cc[0] =
'\x03';
127 ts->c_cc[1] =
'\x1c';
128 ts->c_cc[2] =
'\x7f';
129 ts->c_cc[3] =
'\x15';
130 ts->c_cc[4] =
'\x04';
131 ts->c_cc[5] =
'\x00';
132 ts->c_cc[6] =
'\x01';
133 ts->c_cc[7] =
'\xff';
134 ts->c_cc[8] =
'\x11';
135 ts->c_cc[9] =
'\x13';
136 ts->c_cc[10] =
'\x1a';
137 ts->c_cc[11] =
'\xff';
138 ts->c_cc[12] =
'\x12';
139 ts->c_cc[13] =
'\x0f';
140 ts->c_cc[14] =
'\x17';
141 ts->c_cc[15] =
'\x16';
142 ts->c_cc[16] =
'\xff';
143 ts->c_cc[17] =
'\x00';
144 ts->c_cc[18] =
'\x00';
149 int res = openpty(&amaster, &aslave, name, &term, &win);
155 if (symlink(name, fname) == -1) {
156 fputs(
"KLEE-REPLAY: ERROR: unable to create sym link to tty\n", stderr);
165 perror(
"fork failed\n");
167 }
else if (pid == 0) {
170 fputs(
"KLEE-REPLAY: NOTE: pty slave: setting raw mode\n", stderr);
174 int res = tcgetattr(aslave, &mode);
176 mode.c_iflag = IGNBRK;
177#if defined(__APPLE__) || defined(__FreeBSD__)
178 mode.c_oflag &= ~(ONLCR | OCRNL | ONLRET);
180 mode.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONLRET);
184 mode.c_cc[VTIME] = 0;
185 res = tcsetattr(aslave, TCSANOW, &mode);
193 fputs(
"KLEE-REPLAY: NOTE: pty master: starting\n", stderr);
197 ssize_t res = write(amaster, &contents[pos], flen - pos);
199 if (errno != EINTR) {
200 fputs(
"KLEE-REPLAY: NOTE: pty master: write error\n", stderr);
205 fprintf(stderr,
"KLEE-REPLAY: NOTE: pty master: wrote: %zd (of %d)\n", res, flen);
213 fputs(
"KLEE-REPLAY: NOTE: pty master: closing & waiting\n", stderr);
216 pid_t res = waitpid(pid, &status, 0);
227 fputs(
"KLEE-REPLAY: NOTE: pty master: done\n", stderr);
234 const char *tmpdir) {
236 unsigned flen = dfile->size;
237 char* contents = dfile->contents;
252 }
else if (pid == 0) {
258 fputs(
"KLEE-REPLAY: NOTE: pipe master: starting\n", stderr);
262 int res = write(fds[1], &contents[pos], flen - pos);
274 fputs(
"KLEE-REPLAY: NOTE: pipe master: closing & waiting\n", stderr);
277 pid_t res = waitpid(pid, &status, 0);
288 fputs(
"KLEE-REPLAY: NOTE: pipe master: done\n", stderr);
295 const char *tmpdir) {
296 struct stat64 *s = dfile->stat;
297 char* contents = dfile->contents;
298 unsigned flen = dfile->size;
299 unsigned mode = s->st_mode & 0777;
301 fprintf(stderr,
"KLEE-REPLAY: NOTE: Creating file %s of length %d\n", fname, flen);
304 if (__exe_env.version == 0 && mode == 0)
307 int fd = open(fname, O_CREAT | O_RDWR, mode);
310 fprintf(stderr,
"KLEE-REPLAY: ERROR: Cannot create file %s\n", fname);
314 ssize_t r = write(fd, contents, flen);
315 if (r < 0 || (
unsigned) r != flen) {
316 fprintf(stderr,
"KLEE-REPLAY: ERROR: Cannot write file %s\n", fname);
320 struct timeval tv[2];
321 tv[0].tv_sec = s->st_atime;
323 tv[1].tv_sec = s->st_mtime;
329 lseek(fd, 0, SEEK_SET);
335 const char *target_name,
336 exe_disk_file_t *dfile,
337 const char *tmpdir) {
338 struct stat64 *s = dfile->stat;
339 char tmpname[PATH_MAX];
343 assert((target_fd == -1) ^ (target_name == NULL));
346 snprintf(tmpname,
sizeof(tmpname),
"%s/%s", tmpdir, target_name);
347 else snprintf(tmpname,
sizeof(tmpname),
"%s/fd%d", tmpdir, target_fd);
352 s->st_uid = geteuid();
353 s->st_gid = getegid();
355 if (S_ISLNK(s->st_mode)) {
358 else if (S_ISDIR(s->st_mode)) {
361 else if (S_ISCHR(s->st_mode)) {
364 else if (S_ISFIFO(s->st_mode) ||
365 (target_fd==0 && (s->st_mode & S_IFMT) == 0)) {
373 if (target_fd != -1) {
375 if (dup2(fd, target_fd) < 0) {
376 fprintf(stderr,
"KLEE-REPLAY: ERROR: dup2 failed for target: %d\n", target_fd);
382 if (s->st_nlink > 1) {
384 snprintf(tmp2,
sizeof(tmp2),
"%s/%s.link2", tmpdir, target_name);
385 if (link(target_name, tmp2) < 0) {
402 strcpy(
replay_dir,
"/tmp/klee-replay-XXXXXX");
405 if (tmpdir == NULL) {
406 perror(
"mkdtemp: could not create temporary directory");
410 fprintf(stderr,
"KLEE-REPLAY: NOTE: Storing KLEE replay files in %s\n", tmpdir);
413 for (k=0; k < exe_fs->n_sym_files; k++) {
415 snprintf(name,
sizeof(name),
"%c",
'A' + k);
416 create_file(-1, name, &exe_fs->sym_files[k], tmpdir);
419 if (exe_fs->sym_stdin)
422 if (exe_fs->sym_stdout)
425 if (exe_fs->sym_stdin)
428 if (exe_fs->sym_stdout)
431 for (k=0; k<exe_fs->n_sym_files; ++k)
441 return remove(fpath);
448 fprintf(stderr,
"KLEE-REPLAY: NOTE: removing %s\n",
replay_dir);
451 FTW_DEPTH | FTW_PHYS) == -1) {
461 char fullname[PATH_MAX];
465 strcpy(name,
"stdin");
469 strcpy(name,
"stdout");
473 name[0] =
'A' + index;
475 snprintf(fullname,
sizeof(fullname),
"%s/%s",
replay_dir, name);
476 res = stat(fullname, &s);
482 fprintf(stderr,
"KLEE-REPLAY: WARNING: check_file %d: stat failure\n", index);
486 if (s.st_dev != dfile->stat->st_dev) {
487 fprintf(stderr,
"KLEE-REPLAY: WARNING: check_file %s: dev mismatch: %d vs %d\n",
488 name, (
int) s.st_dev, (
int) dfile->stat->st_dev);
494 if (s.st_mode != dfile->stat->st_mode) {
495 fprintf(stderr,
"KLEE-REPLAY: WARNING: check_file %s: mode mismatch: %#o vs %#o\n",
496 name, s.st_mode, dfile->stat->st_mode);
498 if (s.st_nlink != dfile->stat->st_nlink) {
499 fprintf(stderr,
"KLEE-REPLAY: WARNING: check_file %s: nlink mismatch: %d vs %d\n",
500 name, (
int) s.st_nlink, (
int) dfile->stat->st_nlink);
502 if (s.st_uid != dfile->stat->st_uid) {
503 fprintf(stderr,
"KLEE-REPLAY: WARNING: check_file %s: uid mismatch: %d vs %d\n",
504 name, s.st_uid, dfile->stat->st_uid);
506 if (s.st_gid != dfile->stat->st_gid) {
507 fprintf(stderr,
"KLEE-REPLAY: WARNING: check_file %s: gid mismatch: %d vs %d\n",
508 name, s.st_gid, dfile->stat->st_gid);
510 if (s.st_rdev != dfile->stat->st_rdev) {
511 fprintf(stderr,
"KLEE-REPLAY: WARNING: check_file %s: rdev mismatch: %d vs %d\n",
512 name, (
int) s.st_rdev, (
int) dfile->stat->st_rdev);
514 if (s.st_size != dfile->stat->st_size) {
515 fprintf(stderr,
"KLEE-REPLAY: WARNING: check_file %s: size mismatch: %d vs %d\n",
516 name, (
int) s.st_size, (
int) dfile->stat->st_size);
518 if (s.st_blksize != dfile->stat->st_blksize) {
519 fprintf(stderr,
"KLEE-REPLAY: WARNING: check_file %s: blksize mismatch: %d vs %d\n",
520 name, (
int) s.st_blksize, (
int) dfile->stat->st_blksize);
522 if (s.st_blocks != dfile->stat->st_blocks) {
523 fprintf(stderr,
"KLEE-REPLAY: WARNING: check_file %s: blocks mismatch: %d vs %d\n",
524 name, (
int) s.st_blocks, (
int) dfile->stat->st_blocks);
void *__dso_handle __attribute__((__weak__))
static int create_reg_file(const char *fname, exe_disk_file_t *dfile, const char *tmpdir)
static void create_file(int target_fd, const char *target_name, exe_disk_file_t *dfile, const char *tmpdir)
int wait_for_timeout_or_exit(pid_t pid, const char *name, int *statusp)
Return true if program exited, false if timed out.
static int create_char_dev(const char *fname, exe_disk_file_t *dfile, const char *tmpdir)
int remove_callback(const char *fpath, __attribute__((unused)) const struct stat *sb, __attribute__((unused)) int typeflag, __attribute__((unused)) struct FTW *ftwbuf)
static void check_file(int index, exe_disk_file_t *dfile)
static int create_link(const char *fname, exe_disk_file_t *dfile, const char *tmpdir)
static int create_pipe(const char *fname, exe_disk_file_t *dfile, const char *tmpdir)
static int create_dir(const char *fname, exe_disk_file_t *dfile, const char *tmpdir)
void replay_delete_files()
void replay_create_files(exe_file_system_t *exe_fs)
void process_status(int status, time_t elapsed, const char *pfx)