void arm_kernel_startup(phys_mmap_t* mmap, lpaddr_t initrd_base, size_t initrd_bytes) { g_phys_mmap = mmap; STARTUP_PROGRESS(); #ifdef __XSCALE__ //Hardcoded because bootloader alter image if we pass the correct location //Size of image is obtained by header file which is generated during compilation initrd_base = 0x20000000; initrd_bytes = romfs_cpio_archive_size; #endif const uint8_t* initrd_cpio_base = (uint8_t*)local_phys_to_mem(initrd_base); if (!cpio_archive_valid(initrd_cpio_base, initrd_bytes)) { panic("Invalid initrd filesystem\n"); } /* allocate initial KCB */ kcb_current = (struct kcb *) local_phys_to_mem(alloc_phys(sizeof(*kcb_current))); memset(kcb_current, 0, sizeof(*kcb_current)); assert(kcb_current); spawn_init(BSP_INIT_MODULE_NAME, 0, initrd_cpio_base, initrd_bytes); }
int main(int argc, char **argv) { int i; sigset_t set; #if ENABLE_MPEGTS uint32_t adapter_mask = 0; #endif int log_level = LOG_INFO; int log_options = TVHLOG_OPT_MILLIS | TVHLOG_OPT_STDERR | TVHLOG_OPT_SYSLOG; const char *log_debug = NULL, *log_trace = NULL; gid_t gid = -1; uid_t uid = -1; char buf[512]; FILE *pidfile = NULL; extern int dvb_bouquets_parse; main_tid = pthread_self(); /* Setup global mutexes */ pthread_mutex_init(&fork_lock, NULL); pthread_mutex_init(&global_lock, NULL); pthread_mutex_init(&tasklet_lock, NULL); pthread_mutex_init(&atomic_lock, NULL); pthread_cond_init(>imer_cond, NULL); pthread_cond_init(&tasklet_cond, NULL); TAILQ_INIT(&tasklets); /* Defaults */ tvheadend_webui_port = 9981; tvheadend_webroot = NULL; tvheadend_htsp_port = 9982; tvheadend_htsp_port_extra = 0; time(&dispatch_clock); /* Command line options */ int opt_help = 0, opt_version = 0, opt_fork = 0, opt_firstrun = 0, opt_stderr = 0, opt_syslog = 0, opt_nosyslog = 0, opt_uidebug = 0, opt_abort = 0, opt_noacl = 0, opt_fileline = 0, opt_threadid = 0, opt_libav = 0, opt_ipv6 = 0, opt_satip_rtsp = 0, #if ENABLE_TSFILE opt_tsfile_tuner = 0, #endif opt_dump = 0, opt_xspf = 0, opt_dbus = 0, opt_dbus_session = 0, opt_nobackup = 0, opt_nobat = 0; const char *opt_config = NULL, *opt_user = NULL, *opt_group = NULL, *opt_logpath = NULL, *opt_log_debug = NULL, *opt_log_trace = NULL, *opt_pidpath = "/var/run/tvheadend.pid", #if ENABLE_LINUXDVB *opt_dvb_adapters = NULL, #endif *opt_bindaddr = NULL, *opt_subscribe = NULL, *opt_user_agent = NULL; str_list_t opt_satip_xml = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) }; str_list_t opt_tsfile = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) }; cmdline_opt_t cmdline_opts[] = { { 0, NULL, N_("Generic Options"), OPT_BOOL, NULL }, { 'h', "help", N_("Show this page"), OPT_BOOL, &opt_help }, { 'v', "version", N_("Show version information"),OPT_BOOL, &opt_version }, { 0, NULL, N_("Service Configuration"), OPT_BOOL, NULL }, { 'c', "config", N_("Alternate config path"), OPT_STR, &opt_config }, { 'B', "nobackup", N_("Don't backup config tree at upgrade"), OPT_BOOL, &opt_nobackup }, { 'f', "fork", N_("Fork and run as daemon"), OPT_BOOL, &opt_fork }, { 'u', "user", N_("Run as user"), OPT_STR, &opt_user }, { 'g', "group", N_("Run as group"), OPT_STR, &opt_group }, { 'p', "pid", N_("Alternate pid path"), OPT_STR, &opt_pidpath }, { 'C', "firstrun", N_("If no user account exists then create one with\n" "no username and no password. Use with care as\n" "it will allow world-wide administrative access\n" "to your Tvheadend installation until you edit/create\n" "access-control from within the Tvheadend UI"), OPT_BOOL, &opt_firstrun }, #if ENABLE_DBUS_1 { 'U', "dbus", N_("Enable DBus"), OPT_BOOL, &opt_dbus }, { 'e', "dbus_session", N_("DBus - use the session message bus instead system one"), OPT_BOOL, &opt_dbus_session }, #endif #if ENABLE_LINUXDVB { 'a', "adapters", N_("Only use specified DVB adapters (comma separated)"), OPT_STR, &opt_dvb_adapters }, #endif #if ENABLE_SATIP_SERVER { 0, "satip_rtsp", N_("SAT>IP RTSP port number for server\n" "(default: -1 = disable, 0 = webconfig, standard port is 554)"), OPT_INT, &opt_satip_rtsp }, #endif #if ENABLE_SATIP_CLIENT { 0, "satip_xml", N_("URL with the SAT>IP server XML location"), OPT_STR_LIST, &opt_satip_xml }, #endif { 0, NULL, N_("Server Connectivity"), OPT_BOOL, NULL }, { '6', "ipv6", N_("Listen on IPv6"), OPT_BOOL, &opt_ipv6 }, { 'b', "bindaddr", N_("Specify bind address"), OPT_STR, &opt_bindaddr}, { 0, "http_port", N_("Specify alternative http port"), OPT_INT, &tvheadend_webui_port }, { 0, "http_root", N_("Specify alternative http webroot"), OPT_STR, &tvheadend_webroot }, { 0, "htsp_port", N_("Specify alternative htsp port"), OPT_INT, &tvheadend_htsp_port }, { 0, "htsp_port2", N_("Specify extra htsp port"), OPT_INT, &tvheadend_htsp_port_extra }, { 0, "useragent", N_("Specify User-Agent header for the http client"), OPT_STR, &opt_user_agent }, { 0, "xspf", N_("Use XSPF playlist instead of M3U"), OPT_BOOL, &opt_xspf }, { 0, NULL, N_("Debug Options"), OPT_BOOL, NULL }, { 'd', "stderr", N_("Enable debug on stderr"), OPT_BOOL, &opt_stderr }, { 's', "syslog", N_("Enable debug to syslog"), OPT_BOOL, &opt_syslog }, { 'S', "nosyslog", N_("Disable syslog (all msgs)"), OPT_BOOL, &opt_nosyslog }, { 'l', "logfile", N_("Enable debug to file"), OPT_STR, &opt_logpath }, { 0, "debug", N_("Enable debug subsystems"), OPT_STR, &opt_log_debug }, #if ENABLE_TRACE { 0, "trace", N_("Enable trace subsystems"), OPT_STR, &opt_log_trace }, #endif { 0, "fileline", N_("Add file and line numbers to debug"), OPT_BOOL, &opt_fileline }, { 0, "threadid", N_("Add the thread ID to debug"), OPT_BOOL, &opt_threadid }, #if ENABLE_LIBAV { 0, "libav", N_("More verbose libav log"), OPT_BOOL, &opt_libav }, #endif { 0, "uidebug", N_("Enable webUI debug (non-minified JS)"), OPT_BOOL, &opt_uidebug }, { 'A', "abort", N_("Immediately abort"), OPT_BOOL, &opt_abort }, { 'D', "dump", N_("Enable coredumps for daemon"), OPT_BOOL, &opt_dump }, { 0, "noacl", N_("Disable all access control checks"), OPT_BOOL, &opt_noacl }, { 0, "nobat", N_("Disable DVB bouquets"), OPT_BOOL, &opt_nobat }, { 'j', "join", N_("Subscribe to a service permanently"), OPT_STR, &opt_subscribe }, #if ENABLE_TSFILE || ENABLE_TSDEBUG { 0, NULL, N_("Testing options"), OPT_BOOL, NULL }, { 0, "tsfile_tuners", N_("Number of tsfile tuners"), OPT_INT, &opt_tsfile_tuner }, { 0, "tsfile", N_("tsfile input (mux file)"), OPT_STR_LIST, &opt_tsfile }, #endif #if ENABLE_TSDEBUG { 0, "tsdebug", N_("Output directory for tsdebug"), OPT_STR, &tvheadend_tsdebug }, #endif }; /* Get current directory */ tvheadend_cwd0 = dirname(tvh_strdupa(argv[0])); tvheadend_cwd = dirname(tvh_strdupa(tvheadend_cwd0)); /* Set locale */ setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); /* make sure the timezone is set */ tzset(); /* Process command line */ for (i = 1; i < argc; i++) { /* Find option */ cmdline_opt_t *opt = cmdline_opt_find(cmdline_opts, ARRAY_SIZE(cmdline_opts), argv[i]); if (!opt) show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), _("invalid option specified [%s]"), argv[i]); /* Process */ if (opt->type == OPT_BOOL) *((int*)opt->param) = 1; else if (++i == argc) show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), _("option %s requires a value"), opt->lopt); else if (opt->type == OPT_INT) *((int*)opt->param) = atoi(argv[i]); else if (opt->type == OPT_STR_LIST) { str_list_t *strl = opt->param; if (strl->num < strl->max) strl->str[strl->num++] = argv[i]; } else *((char**)opt->param) = argv[i]; /* Stop processing */ if (opt_help) show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), NULL); if (opt_version) show_version(argv[0]); } /* Additional cmdline processing */ if (opt_nobat) dvb_bouquets_parse = 0; #if ENABLE_LINUXDVB if (!opt_dvb_adapters) { adapter_mask = ~0; } else { char *p, *e; char *r = NULL; char *dvb_adapters = strdup(opt_dvb_adapters); adapter_mask = 0x0; p = strtok_r(dvb_adapters, ",", &r); while (p) { int a = strtol(p, &e, 10); if (*e != 0 || a < 0 || a > 31) { fprintf(stderr, _("Invalid adapter number '%s'\n"), p); free(dvb_adapters); return 1; } adapter_mask |= (1 << a); p = strtok_r(NULL, ",", &r); } free(dvb_adapters); if (!adapter_mask) { fprintf(stderr, "%s", _("No adapters specified!\n")); return 1; } } #endif if (tvheadend_webroot) { char *tmp; if (*tvheadend_webroot == '/') tmp = strdup(tvheadend_webroot); else { tmp = malloc(strlen(tvheadend_webroot)+2); *tmp = '/'; strcpy(tmp+1, tvheadend_webroot); } if (tmp[strlen(tmp)-1] == '/') tmp[strlen(tmp)-1] = '\0'; tvheadend_webroot = tmp; } tvheadend_webui_debug = opt_uidebug; /* Setup logging */ if (isatty(2)) log_options |= TVHLOG_OPT_DECORATE; if (opt_stderr || opt_syslog || opt_logpath) { if (!opt_log_trace && !opt_log_debug) log_debug = "all"; log_level = LOG_DEBUG; if (opt_stderr) log_options |= TVHLOG_OPT_DBG_STDERR; if (opt_syslog) log_options |= TVHLOG_OPT_DBG_SYSLOG; if (opt_logpath) log_options |= TVHLOG_OPT_DBG_FILE; } if (opt_nosyslog) log_options &= ~(TVHLOG_OPT_SYSLOG|TVHLOG_OPT_DBG_SYSLOG); if (opt_fileline) log_options |= TVHLOG_OPT_FILELINE; if (opt_threadid) log_options |= TVHLOG_OPT_THREAD; if (opt_libav) log_options |= TVHLOG_OPT_LIBAV; if (opt_log_trace) { log_level = LOG_TRACE; log_trace = opt_log_trace; } if (opt_log_debug) log_debug = opt_log_debug; tvhlog_init(log_level, log_options, opt_logpath); tvhlog_set_debug(log_debug); tvhlog_set_trace(log_trace); tvhinfo("main", "Log started"); signal(SIGPIPE, handle_sigpipe); // will be redundant later signal(SIGILL, handle_sigill); // see handler.. /* Set priviledges */ if(opt_fork || opt_group || opt_user) { const char *homedir; struct group *grp = getgrnam(opt_group ?: "video"); struct passwd *pw = opt_user ? getpwnam(opt_user) : NULL; if(grp != NULL) { gid = grp->gr_gid; } else { gid = 1; } if (pw != NULL) { if (getuid() != pw->pw_uid) { gid_t glist[16]; int gnum; gnum = get_user_groups(pw, glist, ARRAY_SIZE(glist)); if (gnum > 0 && setgroups(gnum, glist)) { char buf[256] = ""; int i; for (i = 0; i < gnum; i++) snprintf(buf + strlen(buf), sizeof(buf) - 1 - strlen(buf), ",%d", glist[i]); tvhlog(LOG_ALERT, "START", "setgroups(%s) failed, do you have permission?", buf+1); return 1; } } uid = pw->pw_uid; homedir = pw->pw_dir; setenv("HOME", homedir, 1); } else { uid = 1; } } uuid_init(); config_boot(opt_config, gid, uid); tcp_server_preinit(opt_ipv6); http_server_init(opt_bindaddr); // bind to ports only htsp_init(opt_bindaddr); // bind to ports only satip_server_init(opt_satip_rtsp); // bind to ports only if (opt_fork) pidfile = tvh_fopen(opt_pidpath, "w+"); if (gid != -1 && (getgid() != gid) && setgid(gid)) { tvhlog(LOG_ALERT, "START", "setgid(%d) failed, do you have permission?", gid); return 1; } if (uid != -1 && (getuid() != uid) && setuid(uid)) { tvhlog(LOG_ALERT, "START", "setuid(%d) failed, do you have permission?", uid); return 1; } /* Daemonise */ if(opt_fork) { if(daemon(0, 0)) { exit(2); } if(pidfile != NULL) { fprintf(pidfile, "%d\n", getpid()); fclose(pidfile); } /* Make dumpable */ if (opt_dump) { #ifdef PLATFORM_LINUX if (chdir("/tmp")) tvhwarn("START", "failed to change cwd to /tmp"); prctl(PR_SET_DUMPABLE, 1); #else tvhwarn("START", "Coredumps not implemented on your platform"); #endif } umask(0); } tvheadend_running = 1; /* Start log thread (must be done post fork) */ tvhlog_start(); /* Alter logging */ if (opt_fork) tvhlog_options &= ~TVHLOG_OPT_STDERR; if (!isatty(2)) tvhlog_options &= ~TVHLOG_OPT_DECORATE; /* Initialise clock */ pthread_mutex_lock(&global_lock); time(&dispatch_clock); /* Signal handling */ sigfillset(&set); sigprocmask(SIG_BLOCK, &set, NULL); trap_init(argv[0]); /* SSL library init */ OPENSSL_config(NULL); SSL_load_error_strings(); SSL_library_init(); /* Initialise configuration */ notify_init(); idnode_init(); spawn_init(); config_init(opt_nobackup == 0); /** * Initialize subsystems */ epg_in_load = 1; tvhthread_create(&tasklet_tid, NULL, tasklet_thread, NULL); dbus_server_init(opt_dbus, opt_dbus_session); intlconv_init(); api_init(); fsmonitor_init(); libav_init(); tvhtime_init(); profile_init(); imagecache_init(); http_client_init(opt_user_agent); esfilter_init(); bouquet_init(); service_init(); dvb_init(); #if ENABLE_MPEGTS mpegts_init(adapter_mask, &opt_satip_xml, &opt_tsfile, opt_tsfile_tuner); #endif channel_init(); bouquet_service_resolve(); subscription_init(); dvr_config_init(); access_init(opt_firstrun, opt_noacl); #if ENABLE_TIMESHIFT timeshift_init(); #endif tcp_server_init(); webui_init(opt_xspf); #if ENABLE_UPNP upnp_server_init(opt_bindaddr); #endif service_mapper_init(); descrambler_init(); epggrab_init(); epg_init(); dvr_init(); dbus_server_start(); http_server_register(); satip_server_register(); htsp_register(); if(opt_subscribe != NULL) subscription_dummy_join(opt_subscribe, 1); avahi_init(); bonjour_init(); epg_updated(); // cleanup now all prev ref's should have been created epg_in_load = 0; pthread_mutex_unlock(&global_lock); /** * Wait for SIGTERM / SIGINT, but only in this thread */ sigemptyset(&set); sigaddset(&set, SIGTERM); sigaddset(&set, SIGINT); signal(SIGTERM, doexit); signal(SIGINT, doexit); pthread_sigmask(SIG_UNBLOCK, &set, NULL); tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, " "running as PID:%d UID:%d GID:%d, CWD:%s CNF:%s", tvheadend_version, getpid(), getuid(), getgid(), getcwd(buf, sizeof(buf)), hts_settings_get_root()); if(opt_abort) abort(); mainloop(); #if ENABLE_DBUS_1 tvhftrace("main", dbus_server_done); #endif #if ENABLE_UPNP tvhftrace("main", upnp_server_done); #endif tvhftrace("main", satip_server_done); tvhftrace("main", htsp_done); tvhftrace("main", http_server_done); tvhftrace("main", webui_done); tvhftrace("main", fsmonitor_done); tvhftrace("main", http_client_done); tvhftrace("main", tcp_server_done); // Note: the locking is obviously a bit redundant, but without // we need to disable the gtimer_arm call in epg_save() pthread_mutex_lock(&global_lock); tvhftrace("main", epg_save); #if ENABLE_TIMESHIFT tvhftrace("main", timeshift_term); #endif pthread_mutex_unlock(&global_lock); tvhftrace("main", epggrab_done); #if ENABLE_MPEGTS tvhftrace("main", mpegts_done); #endif tvhftrace("main", descrambler_done); tvhftrace("main", service_mapper_done); tvhftrace("main", service_done); tvhftrace("main", channel_done); tvhftrace("main", bouquet_done); tvhftrace("main", dvr_done); tvhftrace("main", subscription_done); tvhftrace("main", access_done); tvhftrace("main", epg_done); tvhftrace("main", avahi_done); tvhftrace("main", bonjour_done); tvhftrace("main", imagecache_done); tvhftrace("main", lang_code_done); tvhftrace("main", api_done); tvhtrace("main", "tasklet enter"); pthread_cond_signal(&tasklet_cond); pthread_join(tasklet_tid, NULL); tvhtrace("main", "tasklet thread end"); tasklet_flush(); tvhtrace("main", "tasklet leave"); tvhftrace("main", hts_settings_done); tvhftrace("main", dvb_done); tvhftrace("main", lang_str_done); tvhftrace("main", esfilter_done); tvhftrace("main", profile_done); tvhftrace("main", intlconv_done); tvhftrace("main", urlparse_done); tvhftrace("main", idnode_done); tvhftrace("main", notify_done); tvhftrace("main", spawn_done); tvhlog(LOG_NOTICE, "STOP", "Exiting HTS Tvheadend"); tvhlog_end(); tvhftrace("main", config_done); if(opt_fork) unlink(opt_pidpath); #if ENABLE_TSFILE free(opt_tsfile.str); #endif free(opt_satip_xml.str); /* OpenSSL - welcome to the "cleanup" hell */ ENGINE_cleanup(); RAND_cleanup(); CRYPTO_cleanup_all_ex_data(); EVP_cleanup(); CONF_modules_free(); #ifndef OPENSSL_NO_COMP COMP_zlib_cleanup(); #endif ERR_remove_state(0); ERR_free_strings(); #ifndef OPENSSL_NO_COMP sk_SSL_COMP_free(SSL_COMP_get_compression_methods()); #endif /* end of OpenSSL cleanup code */ #if ENABLE_DBUS_1 extern void dbus_shutdown(void); if (opt_dbus) dbus_shutdown(); #endif return 0; } /** * */ void tvh_str_set(char **strp, const char *src) { free(*strp); *strp = src ? strdup(src) : NULL; } /** * */ int tvh_str_update(char **strp, const char *src) { if(src == NULL) return 0; free(*strp); *strp = strdup(src); return 1; } /** * */ void scopedunlock(pthread_mutex_t **mtxp) { pthread_mutex_unlock(*mtxp); }
int main (int argc, char *argv[]) { ret_t ret; cherokee_boolean_t single_time; const char *config_file_path; /* Find the worker exec */ figure_worker_path (argv[0]); /* Sanity check */ ret = check_worker_version (argv[0]); if (ret != ret_ok) exit (EXIT_ERROR); set_signals(); single_time = is_single_execution (argc, argv); /* Figure out some stuff */ config_file_path = figure_config_file (argc, argv); use_valgrind = figure_use_valgrind (argc, argv); pid_file_path = figure_pid_file_path (config_file_path); worker_uid = figure_worker_uid (config_file_path); worker_retcode = -1; /* Turn into a daemon */ if (! single_time) { may_daemonize (argc, argv); pid_file_save (pid_file_path, getpid()); } /* Launch the spawning thread */ #ifdef HAVE_SYSV_SEMAPHORES if (! single_time) { ret = spawn_init(); if (ret != ret_ok) { PRINT_MSG_S ("(warning) Couldn't initialize spawn mechanism.\n"); } } #endif while (true) { graceful_restart = false; pid = process_launch (cherokee_worker, argv); if (pid < 0) { PRINT_MSG ("(critical) Couldn't launch '%s'\n", cherokee_worker); exit (EXIT_ERROR); } ret = process_wait (pid); if (single_time) break; usleep ((ret == ret_ok) ? DELAY_RESTARTING : DELAY_ERROR); } if (! single_time) { clean_up(); } return (worker_retcode == 0) ? EXIT_OK : EXIT_ERROR; }
/** Hello, this is main. * \param argc Who knows. * \param argv Who knows. * \return EXIT_SUCCESS I hope. */ int main(int argc, char **argv) { char *confpath = NULL; int xfd, i, screen_nbr, opt, colors_nbr; xcolor_init_request_t colors_reqs[2]; ssize_t cmdlen = 1; xdgHandle xdg; xcb_generic_event_t *event; static struct option long_options[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'v' }, { "config", 1, NULL, 'c' }, { "check", 0, NULL, 'k' }, { NULL, 0, NULL, 0 } }; /* event loop watchers */ ev_io xio = { .fd = -1 }; ev_check xcheck; ev_prepare a_refresh; ev_signal sigint; ev_signal sigterm; ev_signal sighup; /* clear the globalconf structure */ p_clear(&globalconf, 1); globalconf.keygrabber = LUA_REFNIL; globalconf.mousegrabber = LUA_REFNIL; buffer_init(&globalconf.startup_errors); /* save argv */ for(i = 0; i < argc; i++) cmdlen += a_strlen(argv[i]) + 1; globalconf.argv = p_new(char, cmdlen); a_strcpy(globalconf.argv, cmdlen, argv[0]); for(i = 1; i < argc; i++) { a_strcat(globalconf.argv, cmdlen, " "); a_strcat(globalconf.argv, cmdlen, argv[i]); } /* Text won't be printed correctly otherwise */ setlocale(LC_CTYPE, ""); /* Get XDG basedir data */ xdgInitHandle(&xdg); /* init lua */ luaA_init(&xdg); /* check args */ while((opt = getopt_long(argc, argv, "vhkc:", long_options, NULL)) != -1) switch(opt) { case 'v': eprint_version(); break; case 'h': exit_help(EXIT_SUCCESS); break; case 'k': if(!luaA_parserc(&xdg, confpath, false)) { fprintf(stderr, "✘ Configuration file syntax error.\n"); return EXIT_FAILURE; } else { fprintf(stderr, "✔ Configuration file syntax OK.\n"); return EXIT_SUCCESS; } case 'c': if(a_strlen(optarg)) confpath = a_strdup(optarg); else fatal("-c option requires a file name"); break; } globalconf.loop = ev_default_loop(0); ev_timer_init(&globalconf.timer, &luaA_on_timer, 0., 0.); /* register function for signals */ ev_signal_init(&sigint, exit_on_signal, SIGINT); ev_signal_init(&sigterm, exit_on_signal, SIGTERM); ev_signal_init(&sighup, restart_on_signal, SIGHUP); ev_signal_start(globalconf.loop, &sigint); ev_signal_start(globalconf.loop, &sigterm); ev_signal_start(globalconf.loop, &sighup); ev_unref(globalconf.loop); ev_unref(globalconf.loop); ev_unref(globalconf.loop); struct sigaction sa = { .sa_handler = signal_fatal, .sa_flags = 0 }; sigemptyset(&sa.sa_mask); sigaction(SIGSEGV, &sa, 0); /* XLib sucks */ XkbIgnoreExtension(True); /* X stuff */ globalconf.display = XOpenDisplay(NULL); if (globalconf.display == NULL) fatal("cannot open display"); globalconf.default_screen = XDefaultScreen(globalconf.display); globalconf.connection = XGetXCBConnection(globalconf.display); /* Double checking then everything is OK. */ if(xcb_connection_has_error(globalconf.connection)) fatal("cannot open display"); /* Prefetch all the extensions we might need */ xcb_prefetch_extension_data(globalconf.connection, &xcb_big_requests_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_test_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_randr_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_shape_id); /* initialize dbus */ a_dbus_init(); /* Get the file descriptor corresponding to the X connection */ xfd = xcb_get_file_descriptor(globalconf.connection); ev_io_init(&xio, &a_xcb_io_cb, xfd, EV_READ); ev_io_start(globalconf.loop, &xio); ev_check_init(&xcheck, &a_xcb_check_cb); ev_check_start(globalconf.loop, &xcheck); ev_unref(globalconf.loop); ev_prepare_init(&a_refresh, &a_refresh_cb); ev_prepare_start(globalconf.loop, &a_refresh); ev_unref(globalconf.loop); /* Grab server */ xcb_grab_server(globalconf.connection); /* Make sure there are no pending events. Since we didn't really do anything * at all yet, we will just discard all events which we received so far. * The above GrabServer should make sure no new events are generated. */ xcb_aux_sync(globalconf.connection); while ((event = xcb_poll_for_event(globalconf.connection)) != NULL) { /* Make sure errors are printed */ uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event); if(response_type == 0) event_handle(event); p_delete(&event); } for(screen_nbr = 0; screen_nbr < xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); screen_nbr++) { const uint32_t select_input_val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT; /* This causes an error if some other window manager is running */ xcb_change_window_attributes(globalconf.connection, xutil_screen_get(globalconf.connection, screen_nbr)->root, XCB_CW_EVENT_MASK, &select_input_val); } /* Need to xcb_flush to validate error handler */ xcb_aux_sync(globalconf.connection); /* Process all errors in the queue if any. There can be no events yet, so if * this function returns something, it must be an error. */ if (xcb_poll_for_event(globalconf.connection) != NULL) fatal("another window manager is already running"); /* Prefetch the maximum request length */ xcb_prefetch_maximum_request_length(globalconf.connection); /* check for xtest extension */ const xcb_query_extension_reply_t *xtest_query; xtest_query = xcb_get_extension_data(globalconf.connection, &xcb_test_id); globalconf.have_xtest = xtest_query->present; /* Allocate the key symbols */ globalconf.keysyms = xcb_key_symbols_alloc(globalconf.connection); xcb_get_modifier_mapping_cookie_t xmapping_cookie = xcb_get_modifier_mapping_unchecked(globalconf.connection); /* init atom cache */ atoms_init(globalconf.connection); /* init screens information */ screen_scan(); /* init default font and colors */ colors_reqs[0] = xcolor_init_unchecked(&globalconf.colors.fg, "black", sizeof("black") - 1); colors_reqs[1] = xcolor_init_unchecked(&globalconf.colors.bg, "white", sizeof("white") - 1); globalconf.font = draw_font_new("sans 8"); for(colors_nbr = 0; colors_nbr < 2; colors_nbr++) xcolor_init_reply(colors_reqs[colors_nbr]); xutil_lock_mask_get(globalconf.connection, xmapping_cookie, globalconf.keysyms, &globalconf.numlockmask, &globalconf.shiftlockmask, &globalconf.capslockmask, &globalconf.modeswitchmask); /* Get the window tree associated to this screen */ const int screen_max = xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); xcb_query_tree_cookie_t tree_c[screen_max]; /* do this only for real screen */ for(screen_nbr = 0; screen_nbr < screen_max; screen_nbr++) { /* select for events */ const uint32_t change_win_vals[] = { XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_FOCUS_CHANGE }; tree_c[screen_nbr] = xcb_query_tree_unchecked(globalconf.connection, xutil_screen_get(globalconf.connection, screen_nbr)->root); xcb_change_window_attributes(globalconf.connection, xutil_screen_get(globalconf.connection, screen_nbr)->root, XCB_CW_EVENT_MASK, change_win_vals); ewmh_init(screen_nbr); systray_init(screen_nbr); } /* init spawn (sn) */ spawn_init(); /* we will receive events, stop grabbing server */ xcb_ungrab_server(globalconf.connection); /* Parse and run configuration file */ if (!luaA_parserc(&xdg, confpath, true)) fatal("couldn't find any rc file"); scan(tree_c); xcb_flush(globalconf.connection); /* main event loop */ ev_loop(globalconf.loop, 0); /* cleanup event loop */ ev_ref(globalconf.loop); ev_check_stop(globalconf.loop, &xcheck); ev_ref(globalconf.loop); ev_prepare_stop(globalconf.loop, &a_refresh); ev_ref(globalconf.loop); ev_io_stop(globalconf.loop, &xio); awesome_atexit(false); return EXIT_SUCCESS; }
void kmain(void) { kernel_end = (uint64_t)heap_addr; kernel_heap_ptr = (uint8_t*)((uint64_t)&VMA + kernel_end + heap_size) ; UPD = (uint64_t*)((uint64_t)&VMA + kernel_end + 0x3000); KPD = (uint64_t*)((uint64_t)&VMA + kernel_end + 0x4000); PML4 = (uint64_t*)((uint64_t)&VMA + kernel_end); *(KPD + 511) = (kernel_end + 0x4000) | 3; map_mem(mboot_info); #if _GFX_ init_video(); #endif idt_install(); isr_install(); vmem_init(); serial.init(); extern void load_tss(void); load_tss(); extern uint64_t k_tss64_sp; *(uint64_t*)( (uint64_t)&VMA + (uint64_t)&k_tss64_sp ) = 0xFFFFFFFFC0008000; pit_set_freq(2000); // timer tick = 500 us pit_install(); irq_install(); extern void mouse_init(); //mouse_init(); extern void mouse_handler(void*); //irq_install_handler(12, mouse_handler); multiboot_module_t *mod = (multiboot_module_t*)(uint64_t)mboot_info->mods_addr; ramdev_private_t ramdev_private = (ramdev_private_t) { .ptr = (void*)((uint64_t)&VMA + mod->mod_start), .size = (uint32_t)(mod->mod_end - mod->mod_start), }; inode_t ramdisk_inode = (inode_t) { .name = "ramdisk", .type = FS_CHRDEV, .fs = &devfs, .dev = &ramdev, .p = &ramdev_private, }; vfs_create(&dev_root, "/", &ramdisk_inode); inode_t *rootfs = initramfs.load(&ramdisk_inode); vfs_mount_root(rootfs); irq_install_handler(1, kbd_handler); devman.init(); fsman.init(); #if _DBG_CON_ // We should disable debugging by this stage! serial.end(); #endif process_t *init = load_elf("/bin/init"); extern void spawn_init(process_t*); spawn_init(init); for(;;); }
/** Hello, this is main. * \param argc Who knows. * \param argv Who knows. * \return EXIT_SUCCESS I hope. */ int main(int argc, char **argv) { char *confpath = NULL; int xfd, i, opt; ssize_t cmdlen = 1; xdgHandle xdg; bool no_argb = false; xcb_generic_event_t *event; xcb_query_tree_cookie_t tree_c; static struct option long_options[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'v' }, { "config", 1, NULL, 'c' }, { "check", 0, NULL, 'k' }, { "no-argb", 0, NULL, 'a' }, { NULL, 0, NULL, 0 } }; /* event loop watchers */ ev_io xio = { .fd = -1 }; ev_check xcheck; ev_prepare a_refresh; ev_signal sigint; ev_signal sigterm; ev_signal sighup; /* clear the globalconf structure */ p_clear(&globalconf, 1); globalconf.keygrabber = LUA_REFNIL; globalconf.mousegrabber = LUA_REFNIL; buffer_init(&globalconf.startup_errors); /* save argv */ for(i = 0; i < argc; i++) cmdlen += a_strlen(argv[i]) + 1; awesome_argv = p_new(char, cmdlen); a_strcpy(awesome_argv, cmdlen, argv[0]); for(i = 1; i < argc; i++) { a_strcat(awesome_argv, cmdlen, " "); a_strcat(awesome_argv, cmdlen, argv[i]); } /* Text won't be printed correctly otherwise */ setlocale(LC_CTYPE, ""); /* Get XDG basedir data */ xdgInitHandle(&xdg); /* init lua */ luaA_init(&xdg); /* check args */ while((opt = getopt_long(argc, argv, "vhkc:a", long_options, NULL)) != -1) switch(opt) { case 'v': eprint_version(); break; case 'h': exit_help(EXIT_SUCCESS); break; case 'k': if(!luaA_parserc(&xdg, confpath, false)) { fprintf(stderr, "✘ Configuration file syntax error.\n"); return EXIT_FAILURE; } else { fprintf(stderr, "✔ Configuration file syntax OK.\n"); return EXIT_SUCCESS; } case 'c': if(a_strlen(optarg)) confpath = a_strdup(optarg); else fatal("-c option requires a file name"); break; case 'a': no_argb = true; break; } globalconf.loop = ev_default_loop(EVFLAG_NOSIGFD); /* register function for signals */ ev_signal_init(&sigint, exit_on_signal, SIGINT); ev_signal_init(&sigterm, exit_on_signal, SIGTERM); ev_signal_init(&sighup, restart_on_signal, SIGHUP); ev_signal_start(globalconf.loop, &sigint); ev_signal_start(globalconf.loop, &sigterm); ev_signal_start(globalconf.loop, &sighup); ev_unref(globalconf.loop); ev_unref(globalconf.loop); ev_unref(globalconf.loop); struct sigaction sa = { .sa_handler = signal_fatal, .sa_flags = 0 }; sigemptyset(&sa.sa_mask); sigaction(SIGSEGV, &sa, 0); /* X stuff */ globalconf.connection = xcb_connect(NULL, &globalconf.default_screen); if(xcb_connection_has_error(globalconf.connection)) fatal("cannot open display"); globalconf.screen = xcb_aux_get_screen(globalconf.connection, globalconf.default_screen); /* FIXME The following two assignments were swapped on purpose */ if(!no_argb) globalconf.visual = a_default_visual(globalconf.screen); if(!globalconf.visual) globalconf.visual = a_argb_visual(globalconf.screen); globalconf.default_depth = a_visual_depth(globalconf.screen, globalconf.visual->visual_id); globalconf.default_cmap = globalconf.screen->default_colormap; if(globalconf.default_depth != globalconf.screen->root_depth) { // We need our own color map if we aren't using the default depth globalconf.default_cmap = xcb_generate_id(globalconf.connection); xcb_create_colormap(globalconf.connection, XCB_COLORMAP_ALLOC_NONE, globalconf.default_cmap, globalconf.screen->root, globalconf.visual->visual_id); } /* Prefetch all the extensions we might need */ xcb_prefetch_extension_data(globalconf.connection, &xcb_big_requests_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_test_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_randr_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_xinerama_id); /* initialize dbus */ a_dbus_init(); /* Get the file descriptor corresponding to the X connection */ xfd = xcb_get_file_descriptor(globalconf.connection); ev_io_init(&xio, &a_xcb_io_cb, xfd, EV_READ); ev_io_start(globalconf.loop, &xio); ev_check_init(&xcheck, &a_xcb_check_cb); ev_check_start(globalconf.loop, &xcheck); ev_unref(globalconf.loop); ev_prepare_init(&a_refresh, &a_refresh_cb); ev_prepare_start(globalconf.loop, &a_refresh); ev_unref(globalconf.loop); /* Grab server */ xcb_grab_server(globalconf.connection); /* Make sure there are no pending events. Since we didn't really do anything * at all yet, we will just discard all events which we received so far. * The above GrabServer should make sure no new events are generated. */ xcb_aux_sync(globalconf.connection); while ((event = xcb_poll_for_event(globalconf.connection)) != NULL) { /* Make sure errors are printed */ uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event); if(response_type == 0) event_handle(event); p_delete(&event); } { const uint32_t select_input_val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT; /* This causes an error if some other window manager is running */ xcb_change_window_attributes(globalconf.connection, globalconf.screen->root, XCB_CW_EVENT_MASK, &select_input_val); } /* Need to xcb_flush to validate error handler */ xcb_aux_sync(globalconf.connection); /* Process all errors in the queue if any. There can be no events yet, so if * this function returns something, it must be an error. */ if (xcb_poll_for_event(globalconf.connection) != NULL) fatal("another window manager is already running"); /* Prefetch the maximum request length */ xcb_prefetch_maximum_request_length(globalconf.connection); /* check for xtest extension */ const xcb_query_extension_reply_t *xtest_query; xtest_query = xcb_get_extension_data(globalconf.connection, &xcb_test_id); globalconf.have_xtest = xtest_query->present; /* Allocate the key symbols */ globalconf.keysyms = xcb_key_symbols_alloc(globalconf.connection); xcb_get_modifier_mapping_cookie_t xmapping_cookie = xcb_get_modifier_mapping_unchecked(globalconf.connection); /* init atom cache */ atoms_init(globalconf.connection); /* init screens information */ screen_scan(); xutil_lock_mask_get(globalconf.connection, xmapping_cookie, globalconf.keysyms, &globalconf.numlockmask, &globalconf.shiftlockmask, &globalconf.capslockmask, &globalconf.modeswitchmask); /* do this only for real screen */ ewmh_init(); systray_init(); /* init spawn (sn) */ spawn_init(); /* The default GC is just a newly created associated with a window with * depth globalconf.default_depth */ xcb_window_t tmp_win = xcb_generate_id(globalconf.connection); globalconf.gc = xcb_generate_id(globalconf.connection); xcb_create_window(globalconf.connection, globalconf.default_depth, tmp_win, globalconf.screen->root, -1, -1, 1, 1, 0, XCB_COPY_FROM_PARENT, globalconf.visual->visual_id, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP, (const uint32_t []) { globalconf.screen->black_pixel, globalconf.screen->black_pixel, globalconf.default_cmap }); xcb_create_gc(globalconf.connection, globalconf.gc, tmp_win, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, (const uint32_t[]) { globalconf.screen->black_pixel, globalconf.screen->white_pixel }); xcb_destroy_window(globalconf.connection, tmp_win); /* Get the window tree associated to this screen */ tree_c = xcb_query_tree_unchecked(globalconf.connection, globalconf.screen->root); xcb_change_window_attributes(globalconf.connection, globalconf.screen->root, XCB_CW_EVENT_MASK, ROOT_WINDOW_EVENT_MASK); /* we will receive events, stop grabbing server */ xcb_ungrab_server(globalconf.connection); /* Parse and run configuration file */ if (!luaA_parserc(&xdg, confpath, true)) fatal("couldn't find any rc file"); p_delete(&confpath); xdgWipeHandle(&xdg); /* scan existing windows */ scan(tree_c); xcb_flush(globalconf.connection); /* main event loop */ ev_loop(globalconf.loop, 0); /* cleanup event loop */ ev_ref(globalconf.loop); ev_check_stop(globalconf.loop, &xcheck); ev_ref(globalconf.loop); ev_prepare_stop(globalconf.loop, &a_refresh); ev_ref(globalconf.loop); ev_io_stop(globalconf.loop, &xio); awesome_atexit(false); return EXIT_SUCCESS; }