/* * Instead of polling the X connection socket we leave this to * xcb_poll_for_event() which knows better than we can ever know. * */ static void xcb_check_cb(EV_P_ ev_check *w, int revents) { xcb_generic_event_t *event; while ((event = xcb_poll_for_event(conn)) != NULL) { if (event->response_type == 0) { xcb_generic_error_t *error = (xcb_generic_error_t*)event; if (debug_mode) fprintf(stderr, "X11 Error received! sequence 0x%x, error_code = %d\n", error->sequence, error->error_code); free(event); continue; } /* Strip off the highest bit (set if the event is generated) */ int type = (event->response_type & 0x7F); switch (type) { case XCB_KEY_PRESS: handle_key_press((xcb_key_press_event_t*)event); break; case XCB_KEY_RELEASE: handle_key_release((xcb_key_release_event_t*)event); /* If this was the backspace or escape key we are back at an * empty input, so turn off the screen if DPMS is enabled */ if (dpms && input_position == 0) dpms_turn_off_screen(conn); break; case XCB_VISIBILITY_NOTIFY: handle_visibility_notify((xcb_visibility_notify_event_t*)event); break; case XCB_MAP_NOTIFY: if (!dont_fork) { /* After the first MapNotify, we never fork again. We don’t * expect to get another MapNotify, but better be sure… */ dont_fork = true; /* In the parent process, we exit */ if (fork() != 0) exit(0); ev_loop_fork(EV_DEFAULT); } break; case XCB_MAPPING_NOTIFY: handle_mapping_notify((xcb_mapping_notify_event_t*)event); break; case XCB_CONFIGURE_NOTIFY: handle_screen_resize(); break; } free(event); } }
/* * Instead of polling the X connection socket we leave this to * xcb_poll_for_event() which knows better than we can ever know. * */ static void xcb_check_cb(EV_P_ ev_check *w, int revents) { xcb_generic_event_t *event; while ((event = xcb_poll_for_event(conn)) != NULL) { if (event->response_type == 0) { xcb_generic_error_t *error = (xcb_generic_error_t*)event; if (debug_mode) fprintf(stderr, "X11 Error received! sequence 0x%x, error_code = %d\n", error->sequence, error->error_code); free(event); continue; } /* Strip off the highest bit (set if the event is generated) */ int type = (event->response_type & 0x7F); switch (type) { case XCB_KEY_PRESS: handle_key_press((xcb_key_press_event_t*)event); break; case XCB_KEY_RELEASE: /* If this was the backspace or escape key we are back at an * empty input, so turn off the screen if DPMS is enabled, but * only do that after some timeout: maybe user mistyped and * will type again right away */ START_TIMER(dpms_timeout, TSTAMP_N_SECS(inactivity_timeout), turn_off_monitors_cb); break; case XCB_VISIBILITY_NOTIFY: handle_visibility_notify(conn, (xcb_visibility_notify_event_t*)event); break; case XCB_MAP_NOTIFY: if (!dont_fork) { /* After the first MapNotify, we never fork again. We don’t * expect to get another MapNotify, but better be sure… */ dont_fork = true; /* In the parent process, we exit */ if (fork() != 0) exit(0); ev_loop_fork(EV_DEFAULT); } break; case XCB_CONFIGURE_NOTIFY: handle_screen_resize(); break; default: if (type == xkb_base_event) process_xkb_event(event); } free(event); } }
/* * Instead of polling the X connection socket we leave this to * xcb_poll_for_event() which knows better than we can ever know. * */ static void xcb_check_cb(EV_P_ ev_check *w, int revents) { xcb_generic_event_t *event; if (xcb_connection_has_error(conn)) errx(EXIT_FAILURE, "X11 connection broke, did your server terminate?\n"); while ((event = xcb_poll_for_event(conn)) != NULL) { if (event->response_type == 0) { xcb_generic_error_t *error = (xcb_generic_error_t *)event; if (debug_mode) fprintf(stderr, "X11 Error received! sequence 0x%x, error_code = %d\n", error->sequence, error->error_code); free(event); continue; } /* Strip off the highest bit (set if the event is generated) */ int type = (event->response_type & 0x7F); switch (type) { case XCB_BUTTON_PRESS: handle_button_press((xcb_button_press_event_t *)event); break; case XCB_KEY_PRESS: handle_key_press((xcb_key_press_event_t *)event); break; case XCB_VISIBILITY_NOTIFY: handle_visibility_notify(conn, (xcb_visibility_notify_event_t *)event); break; case XCB_MAP_NOTIFY: if (!dont_fork) { /* After the first MapNotify, we never fork again. We don’t * expect to get another MapNotify, but better be sure… */ dont_fork = true; /* In the parent process, we exit */ if (fork() != 0) exit(0); ev_loop_fork(EV_DEFAULT); } break; case XCB_CONFIGURE_NOTIFY: handle_screen_resize(); break; default: if (type == xkb_base_event) process_xkb_event(event); } free(event); } }
/// Do the polling. If on several threads, this is done in every thread. void onion_poller_poll(onion_poller *poller){ ev_default_fork(); ev_loop_fork(poller->loop); poller->stop=0; while(!poller->stop){ sem_wait(poller->sem); ev_run(poller->loop,EVLOOP_ONESHOT); sem_post(poller->sem); } }
/** * Notifies libev that a fork might have been done and forces it * to reinitialize kernel state where needed on the next loop iteration. * * @return boolean false if object has not been initialized */ PHP_METHOD(EventLoop, notifyFork) { event_loop_object *obj = (event_loop_object *)zend_object_store_get_object(getThis() TSRMLS_CC); assert(obj->loop); if(obj->loop) { ev_loop_fork(obj->loop); RETURN_BOOL(1); } RETURN_BOOL(0); }
static void handle_map_notify(xcb_map_notify_event_t *event) { if (fuzzy) { /* Create damage objects for new windows */ xcb_get_window_attributes_reply_t *attribs = xcb_get_window_attributes_reply(conn, xcb_get_window_attributes(conn, event->window), NULL); create_damage(conn, event->window, attribs); } if (!dont_fork) { /* After the first MapNotify, we never fork again. */ dont_fork = true; /* In the parent process, we exit */ if (fork() != 0) exit(0); ev_loop_fork(EV_DEFAULT); } }
int main(int argc, char *argv[]) { struct passwd *pw; char *username; char *image_path = NULL; int ret; struct pam_conv conv = {conv_callback, NULL}; int curs_choice = CURS_NONE; int o; int optind = 0; struct option longopts[] = { {"version", no_argument, NULL, 'v'}, {"nofork", no_argument, NULL, 'n'}, {"beep", no_argument, NULL, 'b'}, {"dpms", no_argument, NULL, 'd'}, {"color", required_argument, NULL, 'c'}, {"pointer", required_argument, NULL, 'p'}, {"debug", no_argument, NULL, 0}, {"help", no_argument, NULL, 'h'}, {"no-unlock-indicator", no_argument, NULL, 'u'}, {"image", required_argument, NULL, 'i'}, {"tiling", no_argument, NULL, 't'}, {"fuzzy", no_argument, NULL, 'f'}, {"radius", required_argument, NULL, 'r'}, {"sigma", required_argument, NULL, 's'}, {"ignore-empty-password", no_argument, NULL, 'e'}, {"inactivity-timeout", required_argument, NULL, 'I'}, {"show-failed-attempts", no_argument, NULL, 'f'}, {NULL, no_argument, NULL, 0}}; if ((pw = getpwuid(getuid())) == NULL) err(EXIT_FAILURE, "getpwuid() failed"); if ((username = pw->pw_name) == NULL) errx(EXIT_FAILURE, "pw->pw_name is NULL.\n"); char *optstring = "hvnbdc:p:ui:tfr:s:eI:l"; while ((o = getopt_long(argc, argv, optstring, longopts, &optind)) != -1) { switch (o) { case 'v': errx(EXIT_SUCCESS, "version " VERSION " © 2010 Michael Stapelberg"); case 'n': dont_fork = true; break; case 'b': beep = true; break; case 'd': fprintf(stderr, "DPMS support has been removed from i3lock. " "Please see the manpage i3lock(1).\n"); break; case 'I': { int time = 0; if (sscanf(optarg, "%d", &time) != 1 || time < 0) errx(EXIT_FAILURE, "invalid timeout, it must be a positive integer\n"); inactivity_timeout = time; break; } case 'c': { char *arg = optarg; /* Skip # if present */ if (arg[0] == '#') arg++; if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", color) != 1) errx(EXIT_FAILURE, "color is invalid, it must be given in " "3-byte hexadecimal format: rrggbb\n"); break; } case 'u': unlock_indicator = false; break; case 'i': image_path = strdup(optarg); break; case 't': tile = true; break; case 'f': fuzzy = true; break; case 'r': sscanf(optarg, "%d", &blur_radius); break; case 's': sscanf(optarg, "%f", &blur_sigma); break; case 'p': if (!strcmp(optarg, "win")) { curs_choice = CURS_WIN; } else if (!strcmp(optarg, "default")) { curs_choice = CURS_DEFAULT; } else { errx(EXIT_FAILURE, "i3lock: Invalid pointer type given. " "Expected one of \"win\" or " "\"default\".\n"); } break; case 'e': ignore_empty_password = true; break; case 0: if (strcmp(longopts[optind].name, "debug") == 0) debug_mode = true; break; case 'l': show_failed_attempts = true; break; default: errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c " "color] [-u] [-p win|default]" " [-i image.png] [-t] [-f] [-r radius] [-s " "sigma] [-e] [-I timeout] [-l]"); } } /* We need (relatively) random numbers for highlighting a random part of * the unlock indicator upon keypresses. */ srand(time(NULL)); /* Initialize PAM */ ret = pam_start("i3lock", username, &conv, &pam_handle); if (ret != PAM_SUCCESS) errx(EXIT_FAILURE, "PAM: %s", pam_strerror(pam_handle, ret)); /* Using mlock() as non-super-user seems only possible in Linux. Users of other * operating systems should use encrypted swap/no swap (or remove the ifdef and * run i3lock as super-user). */ #if defined(__linux__) /* Lock the area where we store the password in memory, we don’t want it to * be swapped to disk. Since Linux 2.6.9, this does not require any * privileges, just enough bytes in the RLIMIT_MEMLOCK limit. */ if (mlock(password, sizeof(password)) != 0) err(EXIT_FAILURE, "Could not lock page in memory, check RLIMIT_MEMLOCK"); #endif /* Initialize connection to X11 */ if ((display = XOpenDisplay(NULL)) == NULL) errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set DISPLAY?"); XSetEventQueueOwner(display, XCBOwnsEventQueue); conn = XGetXCBConnection(display); /* Double checking that connection is good and operatable with xcb */ if (xcb_connection_has_error(conn)) errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set DISPLAY?"); if (xkb_x11_setup_xkb_extension( conn, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION, 0, NULL, NULL, &xkb_base_event, &xkb_base_error) != 1) errx(EXIT_FAILURE, "Could not setup XKB extension."); static const xcb_xkb_map_part_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES | XCB_XKB_MAP_PART_KEY_SYMS | XCB_XKB_MAP_PART_MODIFIER_MAP | XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS | XCB_XKB_MAP_PART_KEY_ACTIONS | XCB_XKB_MAP_PART_VIRTUAL_MODS | XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP); static const xcb_xkb_event_type_t required_events = (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_STATE_NOTIFY); xcb_xkb_select_events(conn, xkb_x11_get_core_keyboard_device_id(conn), required_events, 0, required_events, required_map_parts, required_map_parts, 0); /* When we cannot initially load the keymap, we better exit */ if (!load_keymap()) errx(EXIT_FAILURE, "Could not load keymap"); const char *locale = getenv("LC_ALL"); if (!locale) locale = getenv("LC_CTYPE"); if (!locale) locale = getenv("LANG"); if (!locale) { if (debug_mode) fprintf(stderr, "Can't detect your locale, fallback to C\n"); locale = "C"; } load_compose_table(locale); xinerama_init(); xinerama_query_screens(); /* check if the X server supports DPMS */ xcb_dpms_capable_cookie_t dpmsc = xcb_dpms_capable(conn); xcb_dpms_capable_reply_t *dpmsr; if ((dpmsr = xcb_dpms_capable_reply(conn, dpmsc, NULL))) { dpms_capable = dpmsr->capable; if (!dpmsr->capable && dpms) { if (debug_mode) fprintf(stderr, "Disabling DPMS, X server not DPMS capable\n"); dpms = false; } free(dpmsr); } screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; last_resolution[0] = screen->width_in_pixels; last_resolution[1] = screen->height_in_pixels; xcb_change_window_attributes(conn, screen->root, XCB_CW_EVENT_MASK, (uint32_t[]){XCB_EVENT_MASK_STRUCTURE_NOTIFY}); if (image_path && !fuzzy) { /* Create a pixmap to render on, fill it with the background color */ img = cairo_image_surface_create_from_png(image_path); /* In case loading failed, we just pretend no -i was specified. */ if (cairo_surface_status(img) != CAIRO_STATUS_SUCCESS) { fprintf(stderr, "Could not load image \"%s\": %s\n", image_path, cairo_status_to_string(cairo_surface_status(img))); img = NULL; } } if (fuzzy) { init_blur_coefficents(); } /* Pixmap on which the image is rendered to (if any) */ xcb_pixmap_t bg_pixmap = draw_image(last_resolution); /* open the fullscreen window, already with the correct pixmap in place */ if (fuzzy) { win = open_overlay_window(conn, screen); } else { win = open_fullscreen_window(conn, screen, color, bg_pixmap); } xcb_free_pixmap(conn, bg_pixmap); if (fuzzy) { /* Set up damage notifications */ set_up_damage_notifications(conn, screen); } else { pid_t pid = fork(); /* The pid == -1 case is intentionally ignored here: * While the child process is useful for preventing other windows from * popping up while i3lock blocks, it is not critical. */ if (pid == 0) { /* Child */ close(xcb_get_file_descriptor(conn)); raise_loop(win); exit(EXIT_SUCCESS); } } cursor = create_cursor(conn, screen, win, curs_choice); grab_pointer_and_keyboard(conn, screen, cursor); /* Load the keymap again to sync the current modifier state. Since we first * loaded the keymap, there might have been changes, but starting from now, * we should get all key presses/releases due to having grabbed the * keyboard. */ (void)load_keymap(); /* Initialize the libev event loop. */ main_loop = EV_DEFAULT; if (main_loop == NULL) errx(EXIT_FAILURE, "Could not initialize libev. Bad LIBEV_FLAGS?\n"); struct ev_io *xcb_watcher = calloc(sizeof(struct ev_io), 1); struct ev_check *xcb_check = calloc(sizeof(struct ev_check), 1); struct ev_prepare *xcb_prepare = calloc(sizeof(struct ev_prepare), 1); ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ); ev_io_start(main_loop, xcb_watcher); ev_check_init(xcb_check, xcb_check_cb); ev_check_start(main_loop, xcb_check); ev_prepare_init(xcb_prepare, xcb_prepare_cb); ev_prepare_start(main_loop, xcb_prepare); /* Invoke the event callback once to catch all the events which were * received up until now. ev will only pick up new events (when the X11 * file descriptor becomes readable). */ ev_invoke(main_loop, xcb_check, 0); /* usually fork is called from mapnotify event handler, but in our case * a new window is not created and so the mapnotify event doesn't come */ if (fuzzy && !dont_fork) { dont_fork = true; /* In the parent process, we exit */ if (fork() != 0) exit(0); ev_loop_fork(EV_DEFAULT); } ev_loop(main_loop, 0); }
int main (int argc, char *argv[]) { ptytty::init (); static char opt_fork, opt_opendisplay, opt_quiet; #if ENABLE_PERL static char *opt_eval; #endif #if ENABLE_MLOCK static char opt_lock; #endif for (int i = 1; i < argc; i++) { if (!strcmp (argv [i], "-f") || !strcmp (argv [i], "--fork")) opt_fork = 1; else if (!strcmp (argv [i], "-o") || !strcmp (argv [i], "--opendisplay")) opt_opendisplay = 1; else if (!strcmp (argv [i], "-q") || !strcmp (argv [i], "--quiet")) opt_quiet = 1; #if ENABLE_MLOCK else if (!strcmp (argv [i], "-m") || !strcmp (argv [i], "--mlock")) opt_lock = 1; #endif #if ENABLE_PERL else if (!strcmp (argv [i], "-e") || !strcmp (argv [i], "--eval")) opt_eval = argv [++i]; #endif else { rxvt_log ("%s: unknown option '%s', aborting.\n", argv [0], argv [i]); return EXIT_FAILURE; } } rxvt_init (); #if ENABLE_PERL if (opt_eval) { rxvt_perl.init (); rxvt_perl.eval (opt_eval); } #endif // optionally open display and never release it. if (opt_opendisplay) if (const char *dpy = getenv ("DISPLAY")) displays.get (dpy ? dpy : ":0"); // move string logic into rxvt_display maybe? char *sockname = rxvt_connection::unix_sockname (); unix_listener l (sockname); chdir ("/"); if (!opt_quiet) { printf ("rxvt-unicode daemon listening on %s.\n", sockname); fflush (stdout); } free (sockname); pid_t pid = 0; if (opt_fork) { pid = fork (); } #if ENABLE_MLOCK // Optionally perform an mlockall so this process does not get swapped out. if (opt_lock && !pid) if (mlockall (MCL_CURRENT | MCL_FUTURE) < 0) perror ("unable to lock into ram"); #endif if (opt_fork) { if (pid < 0) { rxvt_log ("unable to fork daemon, aborting.\n"); return EXIT_FAILURE; } else if (pid > 0) _exit (EXIT_SUCCESS); ev_loop_fork (EV_DEFAULT_UC); } ev_run (); return EXIT_SUCCESS; }
static void libev_ctx_reinitialize(void *ctx) { ev_loop_fork(ctx); }
static PyObject * Loop_reset(Loop *self) { ev_loop_fork(self->loop); Py_RETURN_NONE; }
int main(int argc, char **argv) { int do_fork = 1; char *config_fn = DEFAULT_CONFIG_FILE; char *pid_fn = DEFAULT_PID_FILE; int c; evloop = EV_DEFAULT; ev_started_at = ev_time(); opterr = 0; while ((c = getopt (argc, argv, "vhdfc:p:s:l:")) != -1) { switch (c) { case 'v': verbose++; break; case 'h': usage(0); return 0; case 'd': debug = 1; do_fork = 0; break; case 'f': do_fork = 0; break; case 'c': config_fn = optarg; break; case 'p': pid_fn = optarg; break; case 's': server_str_id = strdup(optarg); break; case 'l': server_listen_port = atoi(optarg); if (server_listen_port < 1 || server_listen_port > 65534){ fprintf (stderr, "Invalid listen port: %s.\n", optarg); return 1; } break; case '?': if ((optopt == 'c') || (optopt == 'p') || (optopt == 's') || (optopt == 'l')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return 1; default: usage(); return 1; } } if (optind < argc) { fprintf (stderr, "Unknown option: %s.\n", argv[optind]); return 1; } rtsp_server = rtsp_alloc(); if (!rtsp_server){ return 0; } log_to_stderr = !do_fork; if (!log_to_stderr) openlog(PROGRAM_NAME, LOG_PID, LOG_DAEMON); if (load_config(config_fn)) { fprintf (stderr, "Error loading config file.\n"); return 2; } my_random_init(); if (do_fork){ log_debug("forking..."); if (daemon(0, 0)){ log_error("daemonize failed: %s", strerror(errno)); return -1; } if (write_pid_file(pid_fn)){ log_warning("failed to create pid file"); } ev_loop_fork(evloop); } if (!do_fork) { ev_signal_init (&signal_watcher1, sig_term_cb, SIGINT); ev_signal_start (evloop, &signal_watcher1); } ev_signal_init (&signal_watcher2, sig_term_cb, SIGTERM); ev_signal_start (evloop, &signal_watcher2); ev_signal_init (&signal_watcher3, sig_ignore_cb, SIGHUP); ev_signal_start (evloop, &signal_watcher3); ev_signal_init (&signal_watcher4, sig_ignore_cb, SIGPIPE); ev_signal_start (evloop, &signal_watcher4); if (csconv_init()){ return 0; } if (rtsp_init(rtsp_server)){ csconv_cleanup(); return 0; } elevate_privileges(); setup_io_prio(); drop_privileges(); log_info("starting..."); ev_run(evloop, 0); log_info("cleaning up..."); rtsp_cleanup(rtsp_server); csconv_cleanup(); if (server_str_id) free(server_str_id); log_info("exiting..."); if (!log_to_stderr) closelog(); return 0; }