/* add a child to the list */ static int server_add_child(server_t *s, pid_t pid, backend_t *be) { child_t *child = NULL; dbg_err_if (s == NULL); dbg_err_if (be == NULL); dbg_err_if(child_create(pid, be, &child)); dbg_err_if(children_add(s->children, child)); be->nchild++; return 0; err: return ~0; }
int main(int argc, char* argv[]) { printf("START! pid = %d\n", getpid()); if (!system("./restart.rb")) exit(1); if (signal(SIGUSR1, RestartHandler) == SIG_ERR) { fprintf(stderr, "An error occurred while setting a signal handler.\n"); exit(1); } bool fullscreen = true; s_config = new AppConfig(fullscreen, false, 1280, 800); SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK); SDL_Window* displayWindow; SDL_Renderer* displayRenderer; uint32_t flags = SDL_WINDOW_OPENGL | (s_config->fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); int err = SDL_CreateWindowAndRenderer(s_config->width, s_config->height, flags, &displayWindow, &displayRenderer); if (err == -1 || !displayWindow || !displayRenderer) { fprintf(stderr, "SDL_CreateWindowAndRenderer failed!\n"); } SDL_RendererInfo displayRendererInfo; SDL_GetRendererInfo(displayRenderer, &displayRendererInfo); /* TODO: Check that we have OpenGL */ if ((displayRendererInfo.flags & SDL_RENDERER_ACCELERATED) == 0 || (displayRendererInfo.flags & SDL_RENDERER_TARGETTEXTURE) == 0) { /* TODO: Handle this. We have no render surface and not accelerated. */ fprintf(stderr, "NO RENDERER wtf!\n"); } atexit(SDL_Quit); JOYSTICK_Init(); AppConfig& config = *s_config; config.title = "riftty"; //SDL_WM_SetCaption(config.title.c_str(), config.title.c_str()); //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); /* // clear glClearColor(s_clearColor.x, s_clearColor.y, s_clearColor.z, s_clearColor.w); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_GL_SwapWindow(displayWindow); */ RiftSetup(); RenderInit(); win_init(); init_config(); struct passwd *pw = getpwuid(getuid()); const char *homedir = pw->pw_dir; char config_filename[512]; strncpy(config_filename, homedir, 512); strncat(config_filename, "/.riftty", 512); load_config(config_filename); cs_init(); // TODO: code pages do not want // TODO: determine this based on window-size & font-size or vice versa. cfg.rows = 25; cfg.cols = 80; // TODO: load config from /etc/riffty or ~/.rifttyrc finish_config(); win_reconfig(); // TODO: get SHELL from env cs_reconfig(); // TODO: do not want term_init(); term_reset(); term_resize(cfg.rows, cfg.cols); // TODO: int font_width = 10; int font_height = 10; unsigned short term_width = font_width * cfg.cols; unsigned short term_height = font_height * cfg.rows; char login[128]; strncpy(login, getlogin(), 128); const char* login_argv[] = {"login", "-pfl", login, NULL}; unsigned short rows = cfg.rows; unsigned short cols = cfg.cols; winsize ws = {rows, cols, term_width, term_height}; child_create(login_argv, &ws); bool done = false; while (!done) { JOYSTICK_ClearFlags(); SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: done = true; break; case SDL_MOUSEMOTION: if (event.motion.state & SDL_BUTTON(1)) { // move touch } break; case SDL_MOUSEBUTTONDOWN: if (event.button.button == SDL_BUTTON_LEFT) { // start touch } break; case SDL_MOUSEBUTTONUP: if (event.button.button == SDL_BUTTON_LEFT) { // end touch } break; case SDL_JOYAXISMOTION: JOYSTICK_UpdateMotion(&event.jaxis); break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: JOYSTICK_UpdateButton(&event.jbutton); break; case SDL_KEYDOWN: case SDL_KEYUP: if (ProcessKeyEvent(&event.key)) { done = true; } break; } } if (!done) { if (s_needsRestart) Restart(); unsigned int now = SDL_GetTicks(); // milliseconds float dt = (now - s_ticks) / 1000.0f; // convert to seconds. s_ticks = now; //printf("fps = %.0f\n", 1.0f/dt); Process(dt); Render(dt); } } child_kill(true); win_shutdown(); RiftShutdown(); JOYSTICK_Shutdown(); return 0; }
int main(int argc, char *argv[]) { int backlog = 10; muxer_t *muxers[2] = {NULL, NULL}; status_writer_t *sw = NULL; child_t *child = NULL; int child_status = -1; int ring_buffer_size = 65535; int fds[3] = {-1, -1, -1}; int ii = 0, exit_status = 0, nwritten = 0; pthread_t sw_thread, muxer_threads[2]; char socket_paths[3][PATH_MAX + 1]; char *socket_names[3] = { "stdout.sock", "stderr.sock", "status.sock" }; barrier_t *barrier = NULL; if (argc < 3) { fprintf(stderr, "Usage: %s <socket directory> <cmd>\n", argv[0]); exit(EXIT_FAILURE); } /* Setup listeners on domain sockets */ for (ii = 0; ii < 3; ++ii) { memset(socket_paths[ii], 0, sizeof(socket_paths[ii])); nwritten = snprintf(socket_paths[ii], sizeof(socket_paths[ii]), "%s/%s", argv[1], socket_names[ii]); if (nwritten >= sizeof(socket_paths[ii])) { fprintf(stderr, "Socket path too long\n"); exit_status = 1; goto cleanup; } fds[ii] = create_unix_domain_listener(socket_paths[ii], backlog); DLOG("created listener, path=%s fd=%d", socket_paths[ii], fds[ii]); if (-1 == fds[ii]) { perrorf("Failed creating socket at %s:", socket_paths[ii]); exit_status = 1; goto cleanup; } set_cloexec(fds[ii]); } child = child_create(argv + 2, argc - 2); printf("child_pid=%d\n", child->pid); fflush(stdout); /* Muxers for stdout/stderr */ muxers[0] = muxer_alloc(fds[0], child->stdout[0], ring_buffer_size); muxers[1] = muxer_alloc(fds[1], child->stderr[0], ring_buffer_size); for (ii = 0; ii < 2; ++ii) { if (pthread_create(&muxer_threads[ii], NULL, run_muxer, muxers[ii])) { perrorf("Failed creating muxer thread:"); exit_status = 1; goto cleanup; } DLOG("created muxer thread for socket=%s", socket_paths[ii]); } /* Status writer */ barrier = barrier_alloc(); sw = status_writer_alloc(fds[2], barrier); if (pthread_create(&sw_thread, NULL, run_status_writer, sw)) { perrorf("Failed creating muxer thread:"); exit_status = 1; goto cleanup; } /* Wait for clients on stdout, stderr, and status */ for (ii = 0; ii < 2; ++ii) { muxer_wait_for_client(muxers[ii]); } barrier_wait(barrier); child_continue(child); printf("child active\n"); fflush(stdout); if (-1 == waitpid(child->pid, &child_status, 0)) { perrorf("Waitpid for child failed: "); exit_status = 1; goto cleanup; } DLOG("child exited, status = %d", WEXITSTATUS(child_status)); /* Wait for status writer */ status_writer_finish(sw, child_status); pthread_join(sw_thread, NULL); /* Wait for muxers */ for (ii = 0; ii < 2; ++ii) { muxer_stop(muxers[ii]); pthread_join(muxer_threads[ii], NULL); } DLOG("all done, cleaning up and exiting"); cleanup: if (NULL != child) { child_free(child); } if (NULL != barrier) { barrier_free(barrier); } if (NULL != sw) { status_writer_free(sw); } for (ii = 0; ii < 2; ++ii) { if (NULL != muxers[ii]) { muxer_free(muxers[ii]); } } /* Close accept sockets and clean up paths */ for (ii = 0; ii < 3; ++ii) { if (-1 != fds[ii]) { close(fds[ii]); unlink(socket_paths[ii]); } } return exit_status; }