static int lluv_fill_process_options_(lua_State *L){ static const lluv_uv_const_t FLAGS[] = { { UV_PROCESS_SETUID, "setuid" }, { UV_PROCESS_SETGID, "setgid" }, { UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS, "verbatim" }, { UV_PROCESS_DETACHED, "detached" }, { UV_PROCESS_WINDOWS_HIDE, "hide" }, { 0, NULL } }; uv_process_options_t *opt = (uv_process_options_t *)lua_touserdata(L, 2); unsigned int flags = opt->flags; lua_settop(L, 1); opt->exit_cb = lluv_on_process_exit; if(lua_isstring(L, 1)){ opt->file = (char*) lua_tostring(L, 1); return 1; } luaL_checktype(L, 1, LUA_TTABLE); opt->file = opt_get_string(L, 1, "file", 1, "file option required and must be a string"); opt->cwd = opt_get_string(L, 1, "cwd", 0, "cwd option must be a string"); opt->args = opt_get_sarray(L, 1, "args", 0, (char*)opt->file, "args option must be an array"); opt->env = opt_get_sarray(L, 1, "env", 0, NULL, "env option must be an array"); opt->uid = (uv_uid_t)opt_get_int64 (L, 1, "uid", 0, "uid option must be a number" ); opt->gid = (uv_gid_t)opt_get_int64 (L, 1, "gid", 0, "gid option must be a number" ); if(opt_exists(L, 1, "uid")) flags |= UV_PROCESS_SETUID; if(opt_exists(L, 1, "gid")) flags |= UV_PROCESS_SETGID; rawgets(L, 1, "flags"); opt->flags = flags | lluv_opt_flags_ui(L, -1, 0, FLAGS); lua_pop(L, 1); opt_get_stdio(L, 1, opt); lua_settop(L, 1); return 1; }
// Main int main(int argc, char **argv) { playerc_client_t *client; rtk_app_t *app; mainwnd_t *mainwnd; opt_t *opt; const char *host; int port; int i; int count; double rate; char section[256]; int device_count; device_t devices[PLAYER_MAX_DEVICES]; device_t *device; struct timeval tv, tc = {0, 0}; struct timespec st = {0, (1.0/GUI_UPDATE_RATE) * 1e9}; printf("PlayerViewer %s\n", PLAYER_VERSION); // Initialise rtk lib (after we have read the program options we // want). rtk_init(&argc, &argv); // Register signal handlers signal(SIGINT, sig_quit); signal(SIGQUIT, sig_quit); // Load program options opt = opt_init(argc, argv, NULL); if (!opt) { print_usage(); return -1; } // Pick out some important program options host = opt_get_string(opt, "", "host", NULL); if (!host) host = opt_get_string(opt, "", "h", "localhost"); port = opt_get_int(opt, "", "port", -1); if (port < 0) port = opt_get_int(opt, "", "p", 6665); rate = opt_get_double(opt, "", "rate", 5.0); if(rate < 0.0) rate = 0.0; // Connect to the server printf("Connecting to [%s:%d]\n", host, port); client = playerc_client_create(NULL, host, port); if (playerc_client_connect(client) != 0) { PRINT_ERR1("%s", playerc_error_str()); print_usage(); return -1; } if(rate == 0.0) { printf("Setting delivery mode to PLAYER_DATAMODE_PUSH\n"); // Change the server's data delivery mode. if (playerc_client_set_replace_rule(client, -1, -1, -1, -1, 0) != 0) { PRINT_ERR1("%s", playerc_error_str()); return -1; } // Change the server's data delivery mode. // PLAYERC_DATAMODE_PUSH, PLAYERC_DATAMODE_PULL if (playerc_client_datamode(client, PLAYERC_DATAMODE_PUSH) != 0) { PRINT_ERR1("%s", playerc_error_str()); return -1; } } // Get the available devices. if (playerc_client_get_devlist(client) != 0) { PRINT_ERR1("%s", playerc_error_str()); return -1; } // Create gui app = rtk_app_create(); // Create a window for most of the sensor data mainwnd = mainwnd_create(app, host, port); if (!mainwnd) return -1; // Create a list of available devices, with their gui proxies. device_count = 0; for (i = 0; i < client->devinfo_count; i++) { device = devices + device_count; device->addr = client->devinfos[i].addr; device->drivername = strdup(client->devinfos[i].drivername); // See if the device should be subscribed immediately. snprintf(section, sizeof(section), "%s:%d", interf_to_str(device->addr.interf), device->addr.index); device->subscribe = opt_get_int(opt, section, "", 0); device->subscribe = opt_get_int(opt, section, "subscribe", device->subscribe); if (device->addr.index == 0) { snprintf(section, sizeof(section), "%s", interf_to_str(device->addr.interf)); device->subscribe = opt_get_int(opt, section, "", device->subscribe); device->subscribe = opt_get_int(opt, section, "subscribe", device->subscribe); } // Allow for --position instead of --position2d if(device->addr.interf == PLAYER_POSITION2D_CODE) { snprintf(section, sizeof(section), "%s:%d", PLAYER_POSITION2D_STRING, device->addr.index); device->subscribe = opt_get_int(opt, section, "", device->subscribe); device->subscribe = opt_get_int(opt, section, "subscribe", device->subscribe); if (device->addr.index == 0) { snprintf(section, sizeof(section), "%s", PLAYER_POSITION2D_STRING); device->subscribe = opt_get_int(opt, section, "", device->subscribe); device->subscribe = opt_get_int(opt, section, "subscribe", device->subscribe); } } // Create the GUI proxy for this device. create_proxy(device, opt, mainwnd, client); device_count++; } // Print the list of available devices. printf("Available devices: %s:%d\n", host, port); for (i = 0; i < device_count; i++) { device = devices + i; snprintf(section, sizeof(section), "%s:%d", interf_to_str(device->addr.interf), device->addr.index); printf("%-16s %-40s", section, device->drivername); if (device->proxy) { if (device->subscribe) printf("subscribed"); else printf("ready"); } else printf("unsupported"); printf("\n"); } // Print out a list of unused options. opt_warn_unused(opt); // Start the gui; dont run in a separate thread and dont let it do // its own updates. rtk_app_main_init(app); // start out timer if in pull mode if(rate > 0.0) gettimeofday(&tv, NULL); while (!quit) { // Let gui process messages rtk_app_main_loop(app); if(rate == 0.0) // if we're in push mode { // see if there's data count = playerc_client_peek(client, 50); if (count < 0) { PRINT_ERR1("%s", playerc_error_str()); break; } if (count > 0) { /*proxy = */playerc_client_read_nonblock(client); } } else // we're in pull mode { // we only want to request new data at the target rate gettimeofday(&tc, NULL); if(((tc.tv_sec - tv.tv_sec) + (tc.tv_usec - tv.tv_usec)/1e6) > 1.0/rate) { tv = tc; // this requests a round of data from the server to be read playerc_client_requestdata(client); playerc_client_read_nonblock(client); } else { // sleep for the minimum time we can, so we don't use up too much // processor nanosleep(&st, NULL); } } // Update the devices for (i = 0; i < device_count; i++) { device = devices + i; if(device->proxy) (*(device->fnupdate)) (device->proxy); } // Update the main window if (mainwnd_update(mainwnd) != 0) break; } // Stop the gui rtk_app_main_term(app); // Destroy devices for (i = 0; i < device_count; i++) { device = devices + i; if (device->proxy) (*(device->fndestroy)) (device->proxy); free(device->drivername); } // Disconnect from server if (playerc_client_disconnect(client) != 0) { PRINT_ERR1("%s", playerc_error_str()); return -1; } playerc_client_destroy(client); // For some reason, either of the following calls makes the program // segfault on exit. I haven't figured out why, so I'm commenting them out. - BPG // Destroy the windows //mainwnd_destroy(mainwnd); // Destroy the gui //rtk_app_destroy(app); opt_term(opt); return 0; }