/* * Write to a file in directory watch mode */ int watch_fd_exec_08() { int kq = kqueue(); static char *argv[] = { "prog", "arg1", "arg2", NULL }; postpone_opt = 1; dirwatch_opt = 1; strlcpy(files[0]->fn, "src", sizeof(files[0]->fn)); files[0]->is_dir = 1; watch_file(kq, files[0]); strlcpy(files[1]->fn, "main.py", sizeof(files[1]->fn)); watch_file(kq, files[1]); ctx.event.nlist = 2; EV_SET(&ctx.event.List[0], files[0]->fd, EVFILT_VNODE, 0, NOTE_WRITE, 0, files[0]); EV_SET(&ctx.event.List[1], files[1]->fd, EVFILT_VNODE, 0, NOTE_WRITE, 0, files[1]); watch_loop(kq, argv); ok(ctx.event.nset == 2); ok(ctx.exec.count == 1); ok(ctx.exec.file != 0); ok(ctx.exit.count == 1); ok(strcmp(leading_edge->fn, "main.py") == 0); return 0; }
/* * In restart mode the first action should be to start the server */ int watch_fd_restart_01() { int kq = kqueue(); char *argv[] = { "ruby", "main.rb", NULL }; restart_opt = 1; strlcpy(files[0]->fn, "main.rb", sizeof(files[0]->fn)); watch_file(kq, files[0]); ctx.event.nlist = 0; watch_loop(kq, argv); ok(strcmp(leading_edge->fn, "main.rb") == 0); ok(ctx.event.nset == 1); ok(ctx.event.Set[0].ident); ok(ctx.event.Set[0].filter == EVFILT_VNODE); ok(ctx.event.Set[0].flags == (EV_CLEAR|EV_ADD)); /* open */ ok(ctx.event.Set[0].fflags == (NOTE_ALL)); ok(ctx.event.Set[0].udata == files[0]); ok(ctx.exec.count == 1); ok(ctx.exec.file != 0); ok(strcmp(ctx.exec.file, "ruby") == 0); ok(strcmp(ctx.exec.argv[0], "ruby") == 0); ok(strcmp(ctx.exec.argv[1], "main.rb") == 0); return 0; }
/* * Change a file attribute */ int watch_fd_exec_02() { int kq = kqueue(); static char *argv[] = { "prog", "arg1", "arg2", NULL }; postpone_opt = 1; strlcpy(files[0]->fn, "main.py", sizeof(files[0]->fn)); watch_file(kq, files[0]); ctx.event.nlist = 1; EV_SET(&ctx.event.List[0], files[0]->fd, EVFILT_VNODE, 0, NOTE_ATTRIB, 0, files[0]); watch_loop(kq, argv); ok(ctx.event.nset == 1); ok(ctx.event.Set[0].ident); ok(ctx.event.Set[0].filter == EVFILT_VNODE); ok(ctx.event.Set[0].flags == (EV_CLEAR|EV_ADD)); ok(ctx.event.Set[0].fflags == (NOTE_ALL)); ok(ctx.event.Set[0].udata == files[0]); ok(ctx.exec.count == 0); ok(ctx.exec.file == 0); ok(ctx.exit.count == 0); return 0; }
/* * Extending a file while in restart mode should result in start-kill-restart */ int watch_fd_restart_02() { int kq = kqueue(); char *argv[] = { "ruby", "main.rb", NULL }; restart_opt = 1; strlcpy(files[0]->fn, "main.rb", sizeof(files[0]->fn)); watch_file(kq, files[0]); child_pid = 222; ctx.event.nlist = 0; watch_loop(kq, argv); ok(ctx.event.nset == 1); ok(ctx.event.Set[0].ident); ok(ctx.event.Set[0].filter == EVFILT_VNODE); ok(ctx.event.Set[0].flags == (EV_CLEAR|EV_ADD)); /* open */ ok(ctx.event.Set[0].fflags == (NOTE_ALL)); ok(ctx.event.Set[0].udata == files[0]); ok(ctx.exec.count == 1); ok(ctx.exec.file != 0); ok(strcmp(ctx.exec.file, "ruby") == 0); ok(strcmp(ctx.exec.argv[0], "ruby") == 0); ok(strcmp(ctx.exec.argv[1], "main.rb") == 0); EV_SET(&ctx.event.List[0], files[0]->fd, EVFILT_VNODE, 0, NOTE_EXTEND, 0, files[0]); ctx.event.nlist = 0; watch_loop(kq, argv); ok(ctx.signal.count == 1); ok(ctx.signal.pid == 222); ok(ctx.signal.sig == 15); ok(ctx.exec.count == 2); ok(ctx.exec.file != 0); ok(strcmp(ctx.exec.file, "ruby") == 0); ok(strcmp(ctx.exec.argv[0], "ruby") == 0); ok(strcmp(ctx.exec.argv[1], "main.rb") == 0); return 0; }
/* * Write to a file and then remove it */ int watch_fd_exec_04() { int kq = kqueue(); static char *argv[] = { "prog", "arg1", "arg2", NULL }; postpone_opt = 1; strlcpy(files[0]->fn, "arg1", sizeof(files[0]->fn)); watch_file(kq, files[0]); ctx.event.nlist = 2; EV_SET(&ctx.event.List[0], files[0]->fd, EVFILT_VNODE, 0, NOTE_WRITE, 0, files[0]); EV_SET(&ctx.event.List[1], files[0]->fd, EVFILT_VNODE, 0, NOTE_DELETE, 0, files[0]); watch_loop(kq, argv); ok(ctx.event.nset == 3); ok(ctx.event.Set[0].ident); ok(ctx.event.Set[0].filter == EVFILT_VNODE); ok(ctx.event.Set[0].flags == (EV_CLEAR|EV_ADD)); /* open */ ok(ctx.event.Set[0].fflags == (NOTE_ALL)); ok(ctx.event.Set[0].udata == files[0]->fn); ok(ctx.event.Set[1].ident); ok(ctx.event.Set[1].filter == EVFILT_VNODE); ok(ctx.event.Set[1].flags == EV_DELETE); /* remove */ ok(ctx.event.Set[1].fflags == (NOTE_ALL)); ok(ctx.event.Set[1].udata == files[0]->fn); ok(ctx.event.Set[2].ident); ok(ctx.event.Set[2].filter == EVFILT_VNODE); ok(ctx.event.Set[2].flags == (EV_CLEAR|EV_ADD)); /* reopen */ ok(ctx.event.Set[2].fflags == (NOTE_ALL)); ok(ctx.event.Set[2].udata == files[0]->fn); ok(ctx.exec.count == 1); ok(ctx.exec.file != 0); ok(strcmp(ctx.exec.file, "prog") == 0); ok(strcmp(ctx.exec.argv[0], "prog") == 0); ok(strcmp(ctx.exec.argv[1], "arg1") == 0); ok(strcmp(ctx.exec.argv[2], "arg2") == 0); ok(ctx.exit.count == 0); return 0; }
/* * Add a file to a directory and wait for child to exit */ int watch_fd_exec_06() { int kq = kqueue(); static char *argv[] = { "prog", "arg1", "arg2", NULL }; postpone_opt = 1; strlcpy(files[0]->fn, ".", sizeof(files[0]->fn)); files[0]->is_dir = 1; files[0]->file_count = 1; strlcpy(files[1]->fn, "run.sh", sizeof(files[0]->fn)); watch_file(kq, files[0]); watch_file(kq, files[1]); child_pid = 222; dirwatch_opt = 1; restart_opt = 1; ctx.event.nlist = 1; EV_SET(&ctx.event.List[0], files[0]->fd, EVFILT_VNODE, 0, NOTE_WRITE, 0, files[0]); watch_loop(kq, argv); ok(ctx.event.nset == 2); ok(ctx.event.Set[0].ident); ok(ctx.event.Set[0].filter == EVFILT_VNODE); ok(ctx.event.Set[0].flags == (EV_CLEAR|EV_ADD)); /* open */ ok(ctx.event.Set[0].fflags == (NOTE_ALL)); ok(ctx.event.Set[0].udata == files[0]->fn); ok(ctx.event.Set[1].ident); ok(ctx.event.Set[1].filter == EVFILT_VNODE); ok(ctx.event.Set[1].flags == (EV_CLEAR|EV_ADD)); /* open */ ok(ctx.event.Set[1].fflags == (NOTE_ALL)); ok(ctx.event.Set[1].udata == files[1]->fn); ok(ctx.exec.count == 0); ok(ctx.wait.count == 1); ok(ctx.wait.pid == 222); ok(ctx.exit.count == 1); return 0; }
/* * Write to three files at once */ int watch_fd_exec_03() { int kq = kqueue(); static char *argv[] = { "prog", "arg1", "arg2", NULL }; aggressive_opt = 0; postpone_opt = 1; strlcpy(files[0]->fn, "main.py", sizeof(files[0]->fn)); watch_file(kq, files[0]); strlcpy(files[1]->fn, "util.py", sizeof(files[1]->fn)); watch_file(kq, files[1]); strlcpy(files[2]->fn, "app.py", sizeof(files[2]->fn)); watch_file(kq, files[2]); ctx.event.nlist = 3; EV_SET(&ctx.event.List[0], files[0]->fd, EVFILT_VNODE, 0, NOTE_WRITE, 0, files[0]); EV_SET(&ctx.event.List[1], files[1]->fd, EVFILT_VNODE, 0, NOTE_WRITE, 0, files[1]); EV_SET(&ctx.event.List[2], files[1]->fd, EVFILT_VNODE, 0, NOTE_WRITE, 0, files[2]); watch_loop(kq, argv); ok(strcmp(leading_edge->fn, "main.py") == 0); ok(ctx.event.nset == 3); ok(ctx.event.Set[0].ident); ok(ctx.event.Set[0].filter == EVFILT_VNODE); ok(ctx.event.Set[0].flags == (EV_CLEAR|EV_ADD)); /* open */ ok(ctx.event.Set[0].fflags == (NOTE_ALL)); ok(ctx.event.Set[0].data == 0); ok(ctx.event.Set[0].udata == files[0]->fn); ok(ctx.exec.count == 1); ok(ctx.exec.file != 0); ok(strcmp(ctx.exec.file, "prog") == 0); ok(strcmp(ctx.exec.argv[0], "prog") == 0); ok(strcmp(ctx.exec.argv[1], "arg1") == 0); ok(strcmp(ctx.exec.argv[2], "arg2") == 0); ok(ctx.exit.count == 0); return 0; }
/* * Make a file executable */ int watch_fd_exec_09() { int kq = kqueue(); static char *argv[] = { "prog", "arg1", "arg2", NULL }; postpone_opt = 1; strlcpy(files[0]->fn, "main.py", sizeof(files[0]->fn)); watch_file(kq, files[0]); files[0]->mode = S_IFREG | S_IRUSR | S_IXUSR; ctx.event.nlist = 1; EV_SET(&ctx.event.List[0], files[0]->fd, EVFILT_VNODE, 0, NOTE_ATTRIB, 0, files[0]); watch_loop(kq, argv); ok(ctx.exec.count == 1); ok(ctx.exec.file != 0); ok(strcmp(ctx.exec.file, "prog") == 0); ok(strcmp(ctx.exec.argv[0], "prog") == 0); ok(strcmp(ctx.exec.argv[1], "arg1") == 0); ok(strcmp(ctx.exec.argv[2], "arg2") == 0); ok(ctx.exit.count == 0); return 0; }
/* * The Event Notify Test Runner * run arbitrary commands when files change */ int main(int argc, char *argv[]) { struct rlimit rl; int kq; struct sigaction act; int ttyfd; short argv_index; int n_files; int i; if ((*test_runner_main)) return(test_runner_main(argc, argv)); /* set up pointers to real functions */ xstat = stat; xkevent = kevent; xkillpg = killpg; xexecvp = execvp; xwaitpid = waitpid; xfork = fork; xopen = open; xrealpath = realpath; xfree = free; xwarnx = warnx; xerrx = errx; xlist_dir = list_dir; /* call usage() if no command is supplied */ if (argc < 2) usage(); argv_index = set_options(argv); /* normally a user will exit this utility by do_execting Ctrl-C */ act.sa_flags = 0; act.sa_flags = SA_RESETHAND; act.sa_handler = handle_exit; if (sigemptyset(&act.sa_mask) & (sigaction(SIGINT, &act, NULL) != 0)) err(1, "Failed to set SIGINT handler"); if (sigemptyset(&act.sa_mask) & (sigaction(SIGTERM, &act, NULL) != 0)) err(1, "Failed to set TERM handler"); /* raise soft limit */ getrlimit(RLIMIT_NOFILE, &rl); rl.rlim_cur = min((rlim_t)sysconf(_SC_OPEN_MAX), rl.rlim_max); if (setrlimit(RLIMIT_NOFILE, &rl) != 0) err(1, "setrlimit cannot set rlim_cur to %d", (int)rl.rlim_cur); /* prevent interactive utilities from paging output */ setenv("PAGER", "/bin/cat", 0); /* sequential scan may depend on a 0 at the end */ files = calloc(rl.rlim_cur+1, sizeof(WatchFile *)); if ((kq = kqueue()) == -1) err(1, "cannot create kqueue"); /* read input and populate watch list, skipping non-regular files */ n_files = process_input(stdin, files, rl.rlim_cur); if (n_files == 0) errx(1, "No regular files to watch"); if (n_files == -1) errx(1, "Too many files listed; the hard limit for your login" " class is %d. Please consult" " http://entrproject.org/limits.html", (int)rl.rlim_cur); for (i=0; i<n_files; i++) watch_file(kq, files[i]); /* Attempt to open a tty so that editors don't complain */ ttyfd = xopen(_PATH_TTY, O_RDONLY); if (ttyfd > STDIN_FILENO) { if (dup2(ttyfd, STDIN_FILENO) != 0) xwarnx("can't dup2 to stdin"); close(ttyfd); } watch_loop(kq, argv+argv_index); return 1; }
static int XIOerr(Display *d) { static int reopen = 0, rmax = 1; X_UNLOCK; if (getenv("X11VNC_REOPEN_DISPLAY")) { rmax = atoi(getenv("X11VNC_REOPEN_DISPLAY")); } #if !NO_X11 if (reopen < rmax && getenv("X11VNC_REOPEN_DISPLAY")) { int db = getenv("X11VNC_REOPEN_DEBUG") ? 1 : 0; int sleepmax = 10, i; Display *save_dpy = dpy; char *dstr = strdup(DisplayString(save_dpy)); reopen++; if (getenv("X11VNC_REOPEN_SLEEP_MAX")) { sleepmax = atoi(getenv("X11VNC_REOPEN_SLEEP_MAX")); } rfbLog("*** XIO error: Trying to reopen[%d/%d] display '%s'\n", reopen, rmax, dstr); rfbLog("*** XIO error: Note the reopened state may be unstable.\n"); for (i=0; i < sleepmax; i++) { usleep (1000 * 1000); dpy = XOpenDisplay_wr(dstr); rfbLog("dpy[%d/%d]: %p\n", i+1, sleepmax, dpy); if (dpy) { break; } } last_open_xdisplay = time(NULL); if (dpy) { rfbLog("*** XIO error: Reopened display '%s' successfully.\n", dstr); if (db) rfbLog("*** XIO error: '%s' 0x%x\n", dstr, dpy); scr = DefaultScreen(dpy); rootwin = RootWindow(dpy, scr); if (db) rfbLog("*** XIO error: disable_grabserver\n"); disable_grabserver(dpy, 0); if (db) rfbLog("*** XIO error: xrecord\n"); zerodisp_xrecord(); initialize_xrecord(); if (db) rfbLog("*** XIO error: xdamage\n"); create_xdamage_if_needed(1); if (db) rfbLog("*** XIO error: do_new_fb\n"); if (using_shm) { if (db) rfbLog("*** XIO error: clean_shm\n"); clean_shm(1); } do_new_fb(1); if (db) rfbLog("*** XIO error: check_xevents\n"); check_xevents(1); /* sadly, we can never return... */ if (db) rfbLog("*** XIO error: watch_loop\n"); watch_loop(); clean_up_exit(1); } } #endif interrupted(-1); if (d) {} /* unused vars warning: */ return (*XIOerr_def)(d); }