static gboolean sigterm_cb (gpointer user_data) { status_notify ("%s TERMINATE SIGNAL=%d", id, SIGTERM); quit (EXIT_SUCCESS); return TRUE; }
/* * The virtio core takes the features the Host offers, and copies the ones * supported by the driver into the vdev->features array. Once that's all * sorted out, this routine is called so we can tell the Host which features we * understand and accept. */ static void lg_finalize_features(struct virtio_device *vdev) { unsigned int i, bits; struct lguest_device_desc *desc = to_lgdev(vdev)->desc; /* Second half of bitmap is features we accept. */ u8 *out_features = lg_features(desc) + desc->feature_len; /* Give virtio_ring a chance to accept features. */ vring_transport_features(vdev); /* * The vdev->feature array is a Linux bitmask: this isn't the same as a * the simple array of bits used by lguest devices for features. So we * do this slow, manual conversion which is completely general. */ memset(out_features, 0, desc->feature_len); bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8; for (i = 0; i < bits; i++) { if (test_bit(i, vdev->features)) out_features[i / 8] |= (1 << (i % 8)); } /* Tell Host we've finished with this device's feature negotiation */ status_notify(vdev); }
static void lg_set_status(struct virtio_device *vdev, u8 status) { BUG_ON(!status); to_lgdev(vdev)->desc->status = status; /* Tell Host immediately if we failed. */ if (status & VIRTIO_CONFIG_S_FAILED) status_notify(vdev); }
void run_select_queries(void* data) { int i; CassSession* session = (CassSession*)data; const CassPrepared* select_prepared = NULL; const char* select_query = "SELECT * FROM songs WHERE id = a98d21b2-1900-11e4-b97b-e5e358e71e0d"; #if USE_PREPARED if (prepare_query(session, select_query, &select_prepared) == CASS_OK) { #endif for (i = 0; i < NUM_ITERATIONS; ++i) { select_from_perf(session, select_query, select_prepared); } #if USE_PREPARED cass_prepared_free(select_prepared); } #endif status_notify(&status); }
void run_insert_queries(void* data) { int i; CassSession* session = (CassSession*)data; const CassPrepared* insert_prepared = NULL; const char* insert_query = "INSERT INTO songs (id, title, album, artist, tags) VALUES (?, ?, ?, ?, ?);"; #if USE_PREPARED if (prepare_query(session, insert_query, &insert_prepared) == CASS_OK) { #endif for (i = 0; i < NUM_ITERATIONS; ++i) { insert_into_perf(session, insert_query, insert_prepared); } #if USE_PREPARED cass_prepared_free(insert_prepared); } #endif status_notify(&status); }
static void request_cb (const gchar *name, GHashTable *params) { if (!name) { g_main_loop_quit (loop); return; } if (strcmp (name, "INDICATE-READY") == 0) { void *handler; handler = signal (SIGUSR1, SIG_IGN); if (handler == SIG_IGN) { status_notify ("%s INDICATE-READY", id); kill (getppid (), SIGUSR1); } signal (SIGUSR1, handler); } }
static void lg_reset(struct virtio_device *vdev) { /* 0 status means "reset" */ to_lgdev(vdev)->desc->status = 0; status_notify(vdev); }
static void client_connected_cb (XServer *server, XClient *client) { status_notify ("%s ACCEPT-CONNECT", id); x_client_send_success (client); }
static gboolean sighup_cb (gpointer user_data) { status_notify ("%s DISCONNECT-CLIENTS", id); return TRUE; }
int main (int argc, char **argv) { int i; char *pid_string; gchar *seat = NULL; gchar *mir_id = NULL; gchar *lock_filename; gboolean sharevts = FALSE; int lock_file; GString *status_text; #if !defined(GLIB_VERSION_2_36) g_type_init (); #endif loop = g_main_loop_new (NULL, FALSE); g_unix_signal_add (SIGINT, sigint_cb, NULL); g_unix_signal_add (SIGTERM, sigterm_cb, NULL); g_unix_signal_add (SIGHUP, sighup_cb, NULL); for (i = 1; i < argc; i++) { char *arg = argv[i]; if (arg[0] == ':') { display_number = atoi (arg + 1); } else if (strcmp (arg, "-auth") == 0) { auth_path = argv[i+1]; i++; } else if (strcmp (arg, "-nolisten") == 0) { char *protocol = argv[i+1]; i++; if (strcmp (protocol, "tcp") == 0) ;//listen_tcp = FALSE; else if (strcmp (protocol, "unix") == 0) ;//listen_unix = FALSE; } else if (strcmp (arg, "-nr") == 0) { } else if (strcmp (arg, "-background") == 0) { /* Ignore arg */ i++; } else if (g_str_has_prefix (arg, "vt")) { vt_number = atoi (arg + 2); } else if (strcmp (arg, "-novtswitch") == 0) { /* Ignore VT args */ } else if (strcmp (arg, "-seat") == 0) { seat = argv[i+1]; i++; } else if (strcmp (arg, "-sharevts") == 0) { sharevts = TRUE; } else if (strcmp (arg, "-mir") == 0) { mir_id = argv[i+1]; i++; } else if (strcmp (arg, "-mirSocket") == 0) { /* FIXME */ i++; } else { g_printerr ("Unrecognized option: %s\n" "Use: %s [:<display>] [option]\n" "-auth file Select authorization file\n" "-nolisten protocol Don't listen on protocol\n" "-background [none] Create root window with no background\n" "-nr (Ubuntu-specific) Synonym for -background none\n" "-seat string seat to run on\n" "-sharevts share VTs with another X server\n" "-mir id Mir ID to use\n" "-mirSocket name Mir socket to use\n" "vtxx Use virtual terminal xx instead of the next available\n", arg, argv[0]); return EXIT_FAILURE; } } id = g_strdup_printf ("XMIR-%d", display_number); status_connect (request_cb, id); xserver = x_server_new (display_number); g_signal_connect (xserver, X_SERVER_SIGNAL_CLIENT_CONNECTED, G_CALLBACK (client_connected_cb), NULL); g_signal_connect (xserver, X_SERVER_SIGNAL_CLIENT_DISCONNECTED, G_CALLBACK (client_disconnected_cb), NULL); status_text = g_string_new (""); g_string_printf (status_text, "%s START", id); if (vt_number >= 0) g_string_append_printf (status_text, " VT=%d", vt_number); if (seat != NULL) g_string_append_printf (status_text, " SEAT=%s", seat); if (sharevts) g_string_append (status_text, " SHAREVTS=TRUE"); if (mir_id != NULL) g_string_append_printf (status_text, " MIR-ID=%s", mir_id); status_notify ("%s", status_text->str); g_string_free (status_text, TRUE); config = g_key_file_new (); g_key_file_load_from_file (config, g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "script", NULL), G_KEY_FILE_NONE, NULL); if (g_key_file_has_key (config, "test-xserver-config", "return-value", NULL)) { int return_value = g_key_file_get_integer (config, "test-xserver-config", "return-value", NULL); status_notify ("%s EXIT CODE=%d", id, return_value); return return_value; } lock_filename = g_strdup_printf (".X%d-lock", display_number); lock_path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "tmp", lock_filename, NULL); g_free (lock_filename); lock_file = open (lock_path, O_CREAT | O_EXCL | O_WRONLY, 0444); if (lock_file < 0) { char *lock_contents = NULL; if (g_file_get_contents (lock_path, &lock_contents, NULL, NULL)) { gchar *proc_filename; pid_t pid; pid = atol (lock_contents); g_free (lock_contents); proc_filename = g_strdup_printf ("/proc/%d", pid); if (!g_file_test (proc_filename, G_FILE_TEST_EXISTS)) { gchar *socket_dir; gchar *socket_filename; gchar *socket_path; socket_dir = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "tmp", ".X11-unix", NULL); g_mkdir_with_parents (socket_dir, 0755); socket_filename = g_strdup_printf ("X%d", display_number); socket_path = g_build_filename (socket_dir, socket_filename, NULL); g_printerr ("Breaking lock on non-existant process %d\n", pid); unlink (lock_path); unlink (socket_path); g_free (socket_dir); g_free (socket_filename); g_free (socket_path); } g_free (proc_filename); lock_file = open (lock_path, O_CREAT | O_EXCL | O_WRONLY, 0444); } } if (lock_file < 0) { fprintf (stderr, "Fatal server error:\n" "Server is already active for display %d\n" " If this server is no longer running, remove %s\n" " and start again.\n", display_number, lock_path); g_free (lock_path); lock_path = NULL; return EXIT_FAILURE; } pid_string = g_strdup_printf ("%10ld", (long) getpid ()); if (write (lock_file, pid_string, strlen (pid_string)) < 0) { g_warning ("Error writing PID file: %s", strerror (errno)); return EXIT_FAILURE; } g_free (pid_string); if (!x_server_start (xserver)) return EXIT_FAILURE; g_main_loop_run (loop); cleanup (); return exit_status; }
int main (int argc, char **argv) { #if !defined(GLIB_VERSION_2_36) g_type_init (); #endif status_connect (NULL, NULL); config = g_key_file_new (); g_key_file_load_from_file (config, g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "script", NULL), G_KEY_FILE_NONE, NULL); g_autofree gchar *passwd_path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", "passwd", NULL); if (argc == 2 && strcmp (argv[1], "add") == 0) { /* Create a unique name */ g_autofree gchar *home_dir = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "home", "guest-XXXXXX", NULL); if (!mkdtemp (home_dir)) { g_printerr ("Failed to create home directory %s: %s\n", home_dir, strerror (errno)); return EXIT_FAILURE; } const gchar *username = strrchr (home_dir, '/') + 1; /* Get the largest UID */ gint max_uid = 1000; FILE *passwd = fopen (passwd_path, "r"); if (passwd) { gchar line[1024]; while (fgets (line, 1024, passwd)) { g_auto(GStrv) tokens = g_strsplit (line, ":", -1); if (g_strv_length (tokens) >= 3) { gint uid = atoi (tokens[2]); if (uid > max_uid) max_uid = uid; } } fclose (passwd); } /* Add a new account to the passwd file */ passwd = fopen (passwd_path, "a"); fprintf (passwd, "%s::%d:%d:Guest Account:%s:/bin/sh\n", username, max_uid+1, max_uid+1, home_dir); fclose (passwd); status_notify ("GUEST-ACCOUNT ADD USERNAME=%s", username); /* Print out the username so LightDM picks it up */ g_print ("%s\n", username); return EXIT_SUCCESS; } else if (argc == 3 && strcmp (argv[1], "remove") == 0) { const gchar *username = argv[2]; status_notify ("GUEST-ACCOUNT REMOVE USERNAME=%s", username); /* Open a new file for writing */ FILE *passwd = fopen (passwd_path, "r"); g_autofree gchar *path = g_strdup_printf ("%s~", passwd_path); FILE *new_passwd = fopen (path, "w"); /* Copy the old file, omitting our entry */ g_autofree gchar *prefix = g_strdup_printf ("%s:", username); gchar line[1024]; while (fgets (line, 1024, passwd)) { if (!g_str_has_prefix (line, prefix)) fprintf (new_passwd, "%s", line); } fclose (passwd); fclose (new_passwd); /* Move the new file on the old one */ rename (path, passwd_path); /* Delete home directory */ gchar *command = g_strdup_printf ("rm -r %s/home/%s", g_getenv ("LIGHTDM_TEST_ROOT"), username); if (system (command)) perror ("Failed to delete temp directory"); return EXIT_SUCCESS; } g_printerr ("Usage %s add|remove\n", argv[0]); return EXIT_FAILURE; }
/* read from stream */ static size_t http_read (void *ptr, size_t size, void *d) { http_desc_t *desc = (http_desc_t*)d; pthread_mutex_t mut; /* temporary mutex. What is for? ;) */ int tocopy; /* how much bytes we got? */ /* Init temp mutex */ pthread_mutex_init (&mut, NULL); /* check for reopen */ if (desc->begin > desc->pos || desc->begin + desc->len + 3*HTTP_BLOCK_SIZE < desc->pos) reconnect (desc, NULL); /* wait while the buffer will has entire block */ while (1) { size_t readed; /* check for error */ if (desc->error) { return 0; } /* We will work with buffer... we have to lock it! */ pthread_mutex_lock (&desc->buffer_lock); readed = desc->begin + desc->len - desc->pos; /* done? */ if (readed > 0 && readed >= size) { tocopy = size; break; } /* EOF reached and there is some data */ if (!desc->going && readed > 0) { tocopy = readed; break; } /* EOF reached and there is no data readed*/ if (!desc->going) { tocopy = 0; break; } /* break waiting */ desc->dont_wait = 1; pthread_cond_signal (&desc->dont_wait_signal); /* Allow buffer_thread to use buffer */ pthread_mutex_unlock (&desc->buffer_lock); /* Wait for next portion of data */ if (!desc->new_datablock) { pthread_mutex_lock (&mut); pthread_cond_wait (&desc->new_datablock_signal, &mut); pthread_mutex_unlock (&mut); } else { desc->new_datablock --; } } /* copy result If there are data to copy */ if (tocopy) { memcpy (ptr, desc->buffer + desc->pos - desc->begin, tocopy); desc->pos += tocopy; /* let them know about new state, heh */ status_notify (desc); } /* Allow buffer_thread to use buffer. */ pthread_mutex_unlock (&desc->buffer_lock); return tocopy; } /* http_read */
/* Buffer filling thread. */ static void buffer_thread (http_desc_t *desc) { pthread_mutex_t mut; /* Temporary mutex. */ int BLOCK_SIZE = HTTP_BLOCK_SIZE; void *ibuffer; int rest = 0; int metasize = 0, metapos = 0, extra_read = 0; char *p; /* Init */ pthread_mutex_init (&mut, NULL); if (desc->icy_metaint) { BLOCK_SIZE = (HTTP_BLOCK_SIZE > desc->icy_metaint) ? desc->icy_metaint : HTTP_BLOCK_SIZE; } ibuffer = malloc (BLOCK_SIZE << 1); /* Process while main thread allow it. */ while (desc->going) { void *newbuf; int readed; #ifdef DEBUG_HTTP_BUFFERING print_debug_info (desc); #endif rest = metasize = 0; /* trying to shrink buffer */ pthread_mutex_lock (&desc->buffer_lock); shrink_buffer (desc); pthread_mutex_unlock (&desc->buffer_lock); /* let them know about our state, heh */ status_notify (desc); /* check for overflow */ if (desc->len > http_buffer_size) { /* Notice waiting function that the new block of data has arrived */ desc->new_datablock = 1; pthread_cond_signal (&desc->new_datablock_signal); /* Make pause */ if (!desc->dont_wait) { pthread_mutex_lock (&mut); cond_timedwait_relative (&desc->dont_wait_signal, &mut, calc_time_to_wait (desc)); pthread_mutex_unlock (&mut); } else { desc->dont_wait--; } continue; } /* read to internal buffer */ readed = read_data (desc->sock, ibuffer, BLOCK_SIZE); /* reasons to stop */ if (readed == 0) { desc->going = 0; } else if (readed <0) { desc->error = 1; desc->going = 0; } else { /* Something readed */ /* Metadata stuff */ if (desc->icy_metaint > 0 && (desc->buffer_pos+readed) > desc->icy_metaint) { /* Metadata block is next! */ rest = (desc->buffer_pos+readed) - desc->icy_metaint; p = ((char *)ibuffer); p += (readed-rest); metapos = (readed-rest); if (rest) { metasize = *(int8_t *)p; metasize <<= 4; if (rest < metasize) { /* Uh oh, big trouble ahead, or maybe not? */ extra_read = read_data (desc->sock, ibuffer+readed, metasize); readed += extra_read; rest += extra_read; } if (metasize > 4080) { alsaplayer_error("Invalid metasize (%d)", metasize); } else if (metasize > 0) { p++; p[metasize] = '\0'; pthread_mutex_lock (&desc->meta_lock); if (desc->metadata) { free(desc->metadata); } desc->metadata = malloc(strlen(p)+1); memcpy(desc->metadata, p, strlen(p)); pthread_mutex_unlock (&desc->meta_lock); } else { /* Metadata is zero length */ } } else { alsaplayer_error("Rest = 0???"); } metasize++; /* Length byte */ } else { desc->buffer_pos += readed; } /* These operations are fast. -> doesn't break reader_read */ /* ---------------- lock buffer ( */ pthread_mutex_lock (&desc->buffer_lock); /* enlarge buffer */ newbuf = malloc (desc->len + (BLOCK_SIZE * 2)); /* HTTP_BLOCK_SIZE */ memcpy (newbuf, desc->buffer, desc->len); if (metasize) { memcpy(newbuf + desc->len, ibuffer, metapos); memcpy(newbuf + desc->len + metapos, ibuffer+metapos+metasize, rest - metasize); readed -= metasize; desc->buffer_pos = rest - metasize; } else { memcpy (newbuf + desc->len, ibuffer, readed); } /* switch buffers */ free (desc->buffer); desc->buffer = newbuf; desc->len += readed; /* unlock buffer ) */ pthread_mutex_unlock (&desc->buffer_lock); } /* Notice waiting function that the new block of data has arrived */ desc->new_datablock = 1; pthread_cond_signal (&desc->new_datablock_signal); /* Do wait */ if (desc->going && !desc->dont_wait) { pthread_mutex_lock (&mut); cond_timedwait_relative (&desc->dont_wait_signal, &mut, calc_time_to_wait (desc)); pthread_mutex_unlock (&mut); } if (desc->dont_wait) desc->dont_wait--; } free (ibuffer); pthread_exit (NULL); } /* end of: buffer_thread */