void erts_add_monitor(ErtsMonitor **root, Uint type, Eterm ref, Eterm pid, Eterm name) { void *tstack[STACK_NEED]; int tpos = 0; int dstack[STACK_NEED+1]; int dpos = 1; int state = 0; ErtsMonitor **this = root; Sint c; dstack[0] = DIR_END; for (;;) { if (!*this) { /* Found our place */ state = 1; *this = create_monitor(type,ref,pid,name); break; } else if ((c = CMP_MON_REF(ref,(*this)->ref)) < 0) { /* go left */ dstack[dpos++] = DIR_LEFT; tstack[tpos++] = this; this = &((*this)->left); } else if (c > 0) { /* go right */ dstack[dpos++] = DIR_RIGHT; tstack[tpos++] = this; this = &((*this)->right); } else { /* Equal key is an error for monitors */ erl_exit(1,"Insertion of already present monitor!"); break; } } insertion_rotation(dstack, dpos, tstack, tpos, state); }
static void goa_daemon_init (GoaDaemon *daemon) { static volatile GQuark goa_error_domain = 0; GoaObjectSkeleton *object; gchar *path; /* this will force associating errors in the GOA_ERROR error domain * with org.freedesktop.Goa.Error.* errors via g_dbus_error_register_error_domain(). */ goa_error_domain = GOA_ERROR; goa_error_domain; /* shut up -Wunused-but-set-variable */ notify_init ("goa-daemon"); /* TODO: maybe nicer to pass in a GDBusConnection* construct property */ daemon->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); /* Create object manager */ daemon->object_manager = g_dbus_object_manager_server_new ("/org/gnome/OnlineAccounts"); /* Create and export Manager */ daemon->manager = goa_manager_skeleton_new (); g_signal_connect (daemon->manager, "handle-add-account", G_CALLBACK (on_manager_handle_add_account), daemon); object = goa_object_skeleton_new ("/org/gnome/OnlineAccounts/Manager"); goa_object_skeleton_set_manager (object, daemon->manager); g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (object)); g_object_unref (object); /* create ~/.config/goa-1.0 directory */ path = g_strdup_printf ("%s/goa-1.0", g_get_user_config_dir ()); if (g_mkdir_with_parents (path, 0755) != 0) { goa_warning ("Error creating directory %s: %m", path); } g_free (path); /* set up file monitoring */ path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ()); daemon->home_conf_file_monitor = create_monitor (path, FALSE); if (daemon->home_conf_file_monitor != NULL) g_signal_connect (daemon->home_conf_file_monitor, "changed", G_CALLBACK (on_file_monitor_changed), daemon); g_free (path); /* prime the list of accounts */ goa_daemon_reload_configuration (daemon); /* Export objects */ g_dbus_object_manager_server_set_connection (daemon->object_manager, daemon->connection); }
const void *start_mock_server(char **cmdline) { struct mock_server_info *info = calloc(1, sizeof(*info)); if (info == NULL) { return NULL; } if (!create_monitor(info)) { free(info); return NULL; } info->pid = fork(); assert(info->pid != -1); if (info->pid == 0) { /* Child */ char monitor[1024]; char *argv[1024]; int arg = 0; argv[arg++] = (char*)"./tests/start_mock.sh"; sprintf(monitor, "--harakiri-monitor=localhost:%d", info->port); argv[arg++] = monitor; if (cmdline != NULL) { int ii = 0; while (cmdline[ii] != NULL && arg < 1022) { argv[arg++] = cmdline[ii++]; } } argv[arg++] = NULL; execv(argv[0], argv); abort(); } else { char buffer[1024]; ssize_t offset; ssize_t nr; /* wait until the server connects */ info->client = accept(info->sock, NULL, NULL); assert(info->client != -1); /* Get the port number of the http server */ offset = snprintf(buffer, sizeof(buffer), "localhost:"); nr = recv(info->client, buffer + offset, sizeof(buffer) - (size_t)offset - 1, 0); assert(nr > 0); buffer[nr + offset] = '\0'; info->http = strdup(buffer); wait_for_server(buffer + offset); } return info; }
int main(int argc, char * argv[]) { int ret; int req_num; int i; int top_arg = atoi(argv[1]); char str[PAGE_SIZE]; monitor_t watch_this; fd_set wait_set; /* who we are waiting for events on */ trap_set enter_set; trap_set exit_set; request_t new_request; /* what they want to do now */ pid_t watched1 = atoi(argv[2]); /* who are we watching */ TRAP_ZERO(&enter_set); TRAP_ZERO(&exit_set); for (i = 0; i < top_arg; i++) TRAP_SET(i,&enter_set); ret = create_monitor("/dev/fcap"); if (ret < 0) { perror("encountered an error opening /dev/fcap"); exit(1); } watch_this = ret; /* init select stuff */ FD_ZERO(&wait_set); ret = bind_monitor(watch_this,watched1,enter_set,exit_set); if (ret < 0) { perror("bind_m"); exit(1); } puts("starting watch"); printf("watching %d\n",watched1); req_num = 0; while (1) { FD_SET(watch_this,&wait_set); select(watch_this + 1,&wait_set,NULL,NULL,NULL); ret = read_request(watch_this,&new_request); if (ret != sizeof(request_t)) { perror("block"); exit(1); } //process death if (new_request.event_type == EVENT_PROC_DIED) { FD_CLR(watched1,&wait_set); printf(">>>>>>%d now dead!!\n",new_request.pid); exit(0); //call exit } else if (new_request.event_type == EVENT_CALL_EXIT) { printf("<%d, %s> exited %d\n",new_request.pid, CALL_STR(CALL_NUM(new_request.regs)), new_request.return_value); if (CALL_NUM(new_request.regs) == SYS_socketcall) { struct fcap_socket_info si; printf("creating new socket: %d\n", new_request.return_value); fcap_fetchmeta(watch_this, FCAP_SOCK_INFO, &new_request.return_value,&si,sizeof(struct fcap_socket_info)); printf("WITH TYPE: %d\n",si.type); } //call entry } else { printf("<%d, %s,%d>\n",new_request.pid, CALL_STR(CALL_NUM(new_request.regs)), CALL_NUM(new_request.regs)); if (CALL_NUM(new_request.regs) == SYS_open) { fcap_fetcharg(watch_this,0,str,MAX_STR,TYPE_PATH); printf("opening %s\n",str); } if (CALL_NUM(new_request.regs) == SYS_execve) { fcap_fetcharg(watch_this,0,str,MAX_STR,TYPE_PATH); printf("execing %s\n",str); } if (CALL_NUM(new_request.regs) == SYS_socketcall) { int a,b,c; if (new_request.regs.ebx == SYS_SOCKET) { int err; err = fcap_fetcharg(watch_this,0,&a,sizeof(int),TYPE_SCALAR); if (err) puts(strerror(err)); err = fcap_fetcharg(watch_this,1,&b,sizeof(int),TYPE_SCALAR); if (err) puts(strerror(err)); err = fcap_fetcharg(watch_this,2,&c,sizeof(int),TYPE_SCALAR); if (err) puts(strerror(err)); printf("CALLED socket(%d,%d,%d)\n",a,b,c); } else if (new_request.regs.ebx == SYS_BIND) { int err; struct sockaddr_in sa; err = fcap_fetcharg(watch_this,0,&a,sizeof(int),TYPE_SCALAR); if (err) puts(strerror(err)); err = fcap_fetcharg(watch_this,1,&sa,sizeof(int),TYPE_SCALAR); if (err) puts(strerror(err)); err = fcap_fetcharg(watch_this,2,&c,sizeof(int),TYPE_SCALAR); if (err) puts(strerror(err)); printf("CALLED bind(%d,",a); printf("%s",inet_ntoa(sa.sin_addr)); printf(",%d)\n",c); } else if (new_request.regs.ebx == SYS_CONNECT) { } } } action_monitor(watch_this,CALL_ALLOW); } destroy_monitor(watch_this); return 0; }
int dir_add_monitors(char *path, struct dirent **namelist, int flags, notifier_t *notifier) { static int rec_depth = 0; /* recursion depth */ static int rec_count = 0; /* recursion count */ char dir_path[MAX_DIR_PATH]; char *dir_name; int ndirs; /* directories number */ static int tidx = 0; /* thread id */ static pthread_t tid[MAX_DIR_NUMBER]; int i; if (rec_depth >= RECUR_DEPTH) { --rec_depth; return 0; } ++rec_depth; memset(dir_path, 0, sizeof dir_path); memset(tid, 0, sizeof tid); /* Looks for directories */ ndirs = scandir(path, &namelist, filter_dir, alphasort); if (ndirs < 0) { perror("scandir"); return -1; } #if DEBUG printf("ndirs: %d\n", ndirs); printf("tidx: %d\n", tidx); #endif /* Adds a monitor to the current directory and returns */ if (ndirs == 0) { create_monitor(&tid[tidx++], path, flags, notifier); return 0; } rec_count++; /* Creates a monitor for each directory */ while (ndirs--) { dir_name = namelist[ndirs]->d_name; #if DEBUG printf("(%d) %s/%s\n", ndirs, path, dir_name); #endif snprintf(dir_path, sizeof dir_path, "%s/%s", path, dir_name); dir_add_monitors(dir_path, namelist, flags, notifier); if (namelist[ndirs]) free(namelist[ndirs]); /* Creates a thread to monitor the directory 'dir_path' */ create_monitor(&tid[tidx++], dir_path, flags, notifier); } rec_count--; if (namelist) free(namelist); /* * When the recursion ends, the first function call will wait for the * launched threads. */ if (rec_count == 0) { while (tidx--) { pthread_join(tid[tidx], NULL); } } return 0; }