/* main function */ int main() { int ret; pthread_t child; struct sigaction sa; /* Initialize output */ output_init(); /* Set the signal handler */ sa.sa_flags = SA_RESTART; sa.sa_handler = handler; ret = sigemptyset( &sa.sa_mask ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to empty signal set" ); } /* Install the signal handler for SIGNAL */ ret = sigaction( SIGNAL, &sa, 0 ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to set signal handler" ); } /* Initialize the semaphore */ ret = sem_init( &sem, 0, 0 ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to init a semaphore" ); } /* Create the child thread */ ret = pthread_create( &child, NULL, threaded, NULL ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to create a child thread" ); } /* Let the child thread enter the wait routine... we use sched_yield as there is no certain way to test that the child is waiting for the semaphore... */ sched_yield(); sched_yield(); sched_yield(); /* Ok, now kill the child */ ret = pthread_kill( child, SIGNAL ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to kill the child thread" ); } /* wait that the child receives the signal */ while ( !caught ) sched_yield(); /* Now let the child run and terminate */ ret = sem_post( &sem ); if ( ret != 0 ) { UNRESOLVED( errno, "Failed to post the semaphore" ); } ret = pthread_join( child, NULL ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to join the thread" ); } /* terminate */ ret = sem_destroy( &sem ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to destroy the semaphore" ); } /* Test passed */ #if VERBOSE > 0 output( "Test passed\n" ); #endif PASSED; }
int control_loop_setup( int ms_period, int ctrl_gain, int ubisense, double *offset_r, double *offset_p ) { struct sigaction act; /* initialize global variables */ running = 1; period = ms_period / 1000.0; us_period = ms_period * 1000; pos_ctrl_gain = ctrl_gain; ubisense_enabled = ubisense; heli_state = HELI_STATE_SHUTDOWN; heli_mode = HELI_MODE_POS_CTRL; heli_settled = 1; yaw_wn_imu = 0; yaw_wn_cmd = 0; new_data_x = 0; new_data_y = 0; new_data_z = 0; offset_roll = offset_r; offset_pitch = offset_p; cmd_roll = 0; cmd_pitch = 0; next_period = 0; motor_speed_revving = 0; motor_speed_liftoff = 0; act.sa_handler = signal_handler; act.sa_handler = int_handler; /* initialize signal handlers */ if( sigaction( SIGUSR1, &act, NULL ) || sigaction( SIGINT, &act, NULL ) ) { perror( "sigaction" ); } /* initialize filter objects */ outlier_filter_init( &cof_out_x, "OUT_X", COF_MDIFF_POS, COF_LIMIT_POS ); outlier_filter_init( &cof_out_y, "OUT_Y", COF_MDIFF_POS, COF_LIMIT_POS ); iir_lp_filter_init ( &iir_acc_x, "ACC_X", IIR_GAIN_LACC ); iir_lp_filter_init ( &iir_acc_y, "ACC_Y", IIR_GAIN_LACC ); iir_lp_filter_init ( &iir_acc_z, "ACC_Z", IIR_GAIN_LACC ); iir_lp_filter_init ( &iir_cmd_roll, "CMD_Roll", IIR_GAIN_RCMD ); iir_lp_filter_init ( &iir_cmd_pitch, "CMD_Pitch", IIR_GAIN_RCMD ); iir_lp_filter_init ( &iir_cmd_yaw, "CMD_Yaw", IIR_GAIN_RCMD ); iir_lp_filter_init ( &iir_cmd_z, "CMD_Z", IIR_GAIN_RCMD ); average_filter_init( &avg_bmu_maps, "BMU_MAPS", AVG_SIZE_MAPS ); median_filter_init ( &med_bmu_temp, "BMU_Temp", MED_SIZE_TEMP ); median_filter_init ( &med_bmu_batt, "BMU_Batt", MED_SIZE_BATT ); attitude_ekf_init ( &ekf_att_roll, "ATT_Roll", EKF_ATT_STD_E, EKF_ATT_STD_W, EKF_ATT_PH_SH, period ); attitude_ekf_init ( &ekf_att_pitch, "ATT_Pitch", EKF_ATT_STD_E, EKF_ATT_STD_W, EKF_ATT_PH_SH, period ); attitude_ekf_init ( &ekf_att_yaw, "ATT_Yaw", EKF_ATT_STD_E, EKF_ATT_STD_W, EKF_ATT_PH_SH, period ); position_ekf_init ( &ekf_pos_x, "POS_X", EKF_POS_STD_P, EKF_POS_STD_V, EKF_POS_STD_A, period ); position_ekf_init ( &ekf_pos_y, "POS_Y", EKF_POS_STD_P, EKF_POS_STD_V, EKF_POS_STD_A, period ); position_ekf_init ( &ekf_pos_z, "POS_Z", EKF_POS_STD_P, EKF_POS_STD_V, EKF_POS_STD_A, period ); /* initialize controller objects */ controller_init ( &ctrl_roll, "Roll", CTRL_PIDD_DEF, period ); controller_init ( &ctrl_pitch, "Pitch", CTRL_PIDD_DEF, period ); controller_init ( &ctrl_yaw, "Yaw", CTRL_PIDD_DEF, period ); controller_init ( &ctrl_x, "X", CTRL_PIDD_X_Y, period ); controller_init ( &ctrl_y, "Y", CTRL_PIDD_X_Y, period ); controller_init ( &ctrl_z, "Z", CTRL_PIDD_DEF, period ); /* initialize transformations */ transformation_init( ); /* clear data structures */ memset( &command_data, 0, sizeof( command_data ) ); memset( &javiator_data, 0, sizeof( javiator_data ) ); memset( &sensor_data, 0, sizeof( sensor_data ) ); memset( &motor_signals, 0, sizeof( motor_signals ) ); memset( &motor_offsets, 0, sizeof( motor_offsets ) ); memset( &trace_data, 0, sizeof( trace_data ) ); return( 0 ); }
int main( int argc, char *argv[] ) { int port = LISTEN_PORT; /* set the port default value as PORT */ int listen_fd; /* define server listen fd */ int conn_fd; /* define connect fd */ struct sockaddr_in server_addr, client_addr; socklen_t client_addr_len; char str[32]; char buf[32]; int total = 0, i, j; int ret; struct sigaction newact, oldact; /* set our handler, save the old one */ newact.sa_handler = sig_int; newact.sa_flags = 0; sigaction(SIGINT, &newact, &oldact ); /* set our handler, save the old one */ newact.sa_handler = sig_pipe; newact.sa_flags = 0; sigaction(SIGPIPE, &newact, &oldact ); /* get the listen port from command line argv[1] */ if( argv[1] ) port = atoi( argv[1] ); printf( "server begin at port: %d \n", port ); /* create socket and listen */ listen_fd = socket( AF_INET,SOCK_STREAM, 0); /* fill in the struct */ bzero( &server_addr, sizeof(server_addr) ); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl( INADDR_ANY ); server_addr.sin_port = htons( port ); /* bind server listen port */ ret = bind( listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr) ); if( ret < 0 ) printf( "server bind error !\n" ); /* server begin to listen */ listen( listen_fd, 8 ); printf( "Accepting connections: %d \n", port ); client_addr_len = sizeof( client_addr ); conn_fd = accept( listen_fd, (struct sockaddr *)&client_addr, &client_addr_len ); printf( "client is connected from %s:%d! \n", inet_ntop(AF_INET, &client_addr.sin_addr, str, sizeof(str)), ntohs(client_addr.sin_port) ); while( 1 ) { if( (ret = read(conn_fd, buf, 32)) > 0 ) { buf[ret] = '\0'; printf( "From Client: %s", buf ); printf( "Write To Client: %s \n", buf ); write( conn_fd, buf, strlen(buf) ); } else if( ret == 0 ) { printf( "client socket is closed! \n" ); close( conn_fd ); exit( 0 ); } } return 0; }
void SignalHandler::setup_default_handlers(std::string path) { #ifndef RBX_WINDOWS report_path[0] = 0; // Calculate the report_path if(path.rfind("/") == std::string::npos) { if(char* home = getenv("HOME")) { snprintf(report_path, PATH_MAX, "%s/.rbx", home); pid_t pid = getpid(); bool use_dir = false; struct stat s; if(stat(report_path, &s) != 0) { if(mkdir(report_path, S_IRWXU) == 0) use_dir = true; } else if(S_ISDIR(s.st_mode)) { use_dir = true; } if(use_dir) { snprintf(report_path + strlen(report_path), PATH_MAX, "/%s_%d", path.c_str(), pid); } else { snprintf(report_path, PATH_MAX, "%s/.%s_%d", home, path.c_str(), pid); } } } if(!report_path[0]) { strncpy(report_path, path.c_str(), PATH_MAX-1); } // Test that we can actually use this path. int fd = open(report_path, O_RDONLY | O_CREAT, 0666); if(!fd) { char buf[RBX_STRERROR_BUFSIZE]; char* err = RBX_STRERROR(errno, buf, RBX_STRERROR_BUFSIZE); std::cerr << "Unable to use " << report_path << " for crash reports.\n"; std::cerr << "Unable to open path: " << err << "\n"; // Don't use the home dir path even, just use stderr report_path[0] = 0; } else { close(fd); unlink(report_path); } // Get the machine info. uname(&machine_info); struct sigaction action; action.sa_handler = null_func; action.sa_flags = 0; sigfillset(&action.sa_mask); sigaction(SIGVTALRM, &action, NULL); // Some extensions expect SIGALRM to be defined, because MRI does. // We'll just use a noop for it. action.sa_handler = null_func; sigaction(SIGALRM, &action, NULL); // Ignore sigpipe. action.sa_handler = SIG_IGN; sigaction(SIGPIPE, &action, NULL); #ifdef USE_EXECINFO // If we have execinfo, setup some crash handlers if(!getenv("DISABLE_SEGV")) { action.sa_handler = segv_handler; sigaction(SIGSEGV, &action, NULL); sigaction(SIGBUS, &action, NULL); sigaction(SIGILL, &action, NULL); sigaction(SIGFPE, &action, NULL); sigaction(SIGABRT, &action, NULL); } #endif // USE_EXEC_INFO #else signal(SIGTERM, quit_handler); #endif // ifndef RBX_WINDOWS }
int main(int argc, char *argv[]) { struct sigaction act; int argn = 1, ret; { const char *home = getenv("HOME"); if (home) { char *conffile = xmalloc(strlen(home) + sizeof(CONFIG_FILE) + 2); strcpy(conffile, home); strcat(conffile, "/" CONFIG_FILE); xconfig_parse_file(evilwm_options, conffile); free(conffile); } } ret = xconfig_parse_cli(evilwm_options, argc, argv, &argn); if (ret == XCONFIG_MISSING_ARG) { fprintf(stderr, "%s: missing argument to `%s'\n", argv[0], argv[argn]); exit(1); } else if (ret == XCONFIG_BAD_OPTION) { if (0 == strcmp(argv[argn], "-h") || 0 == strcmp(argv[argn], "--help")) { helptext(); exit(0); #ifdef STDIO } else if (0 == strcmp(argv[argn], "-V") || 0 == strcmp(argv[argn], "--version")) { LOG_INFO("evilwm version " VERSION "\n"); exit(0); #endif } else { helptext(); exit(1); } } if (opt_grabmask1) grabmask1 = parse_modifiers(opt_grabmask1); if (opt_grabmask2) grabmask2 = parse_modifiers(opt_grabmask2); if (opt_altmask) altmask = parse_modifiers(opt_altmask); wm_exit = 0; act.sa_handler = handle_signal; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGTERM, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGHUP, &act, NULL); setup_display(); event_main_loop(); /* Quit Nicely */ while (clients_stacking_order) remove_client(clients_stacking_order->data); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); if (font) XFreeFont(dpy, font); { int i; for (i = 0; i < num_screens; i++) { ewmh_deinit_screen(&screens[i]); XFreeGC(dpy, screens[i].invert_gc); XInstallColormap(dpy, DefaultColormap(dpy, i)); } } free(screens); XCloseDisplay(dpy); return 0; }
int main(int argc, char *argv[]) { const int STACK_SIZE = 65536; /* Stack size for cloned child */ char *stack; /* Start of stack buffer area */ char *stackTop; /* End of stack buffer area */ int flags; /* Flags for cloning child */ ChildParams cp; /* Passed to child function */ const mode_t START_UMASK = S_IWOTH; /* Initial umask setting */ struct sigaction sa; char *p; int status; ssize_t s; pid_t pid; printf("Parent: PID=%ld PPID=%ld\n", (long) getpid(), (long) getppid()); /* Set up an argument structure to be passed to cloned child, and set some process attributes that will be modified by child */ cp.exitStatus = 22; /* Child will exit with this status */ umask(START_UMASK); /* Initialize umask to some value */ cp.umask = S_IWGRP; /* Child sets umask to this value */ cp.fd = open("/dev/null", O_RDWR); /* Child will close this fd */ if (cp.fd == -1) errExit("open"); cp.signal = SIGTERM; /* Child will change disposition */ if (signal(cp.signal, SIG_IGN) == SIG_ERR) errExit("signal"); /* Initialize clone flags using command-line argument (if supplied) */ flags = 0; if (argc > 1) { for (p = argv[1]; *p != '\0'; p++) { if (*p == 'd') flags |= CLONE_FILES; else if (*p == 'f') flags |= CLONE_FS; else if (*p == 's') flags |= CLONE_SIGHAND; else if (*p == 'v') flags |= CLONE_VM; else usageError(argv[0]); } } /* Allocate stack for child */ stack = malloc(STACK_SIZE); if (stack == NULL) errExit("malloc"); stackTop = stack + STACK_SIZE; /* Assume stack grows downward */ /* Establish handler to catch child termination signal */ if (CHILD_SIG != 0) { sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = grimReaper; if (sigaction(CHILD_SIG, &sa, NULL) == -1) errExit("sigaction"); } /* Create child; child commences execution in childFunc() */ if (clone(childFunc, stackTop, flags | CHILD_SIG, &cp) == -1) errExit("clone"); /* Parent falls through to here. Wait for child; __WCLONE option is required for child notifying with signal other than SIGCHLD. */ pid = waitpid(-1, &status, (CHILD_SIG != SIGCHLD) ? __WCLONE : 0); if (pid == -1) errExit("waitpid"); printf(" Child PID=%ld\n", (long) pid); printWaitStatus(" Status: ", status); /* Check whether changes made by cloned child have affected parent */ printf("Parent - checking process attributes:\n"); if (umask(0) != START_UMASK) printf(" umask has changed\n"); else printf(" umask has not changed\n"); s = write(cp.fd, "Hello world\n", 12); if (s == -1 && errno == EBADF) printf(" file descriptor %d has been closed\n", cp.fd); else if (s == -1) printf(" write() on file descriptor %d failed (%s)\n", cp.fd, strerror(errno)); else printf(" write() on file descriptor %d succeeded\n", cp.fd); if (sigaction(cp.signal, NULL, &sa) == -1) errExit("sigaction"); if (sa.sa_handler != SIG_IGN) printf(" signal disposition has changed\n"); else printf(" signal disposition has not changed\n"); exit(EXIT_SUCCESS); }
int main(int argc, char** argv) { char *buffer = NULL; int portno = 0, stop, optval; socklen_t clilen; struct sockaddr_in serv_addr, cli_addr; struct sigaction action_CHLD; struct sigaction action_ALRM; /* Preliminary signal configuration: * SIGCHLD and SIGALRM are used with different handler * configure each handler to mask the other signal during it's process * Note: within a handler called upon a signal SIGX, the SIGX signal is * automatically de-activated. */ sigemptyset(&block_sigs); sigaddset(&block_sigs, SIGCHLD); sigaddset(&block_sigs, SIGALRM); action_CHLD.sa_flags = SA_RESTART; action_CHLD.sa_handler = SIGCHLD_handler; sigemptyset(&(action_CHLD.sa_mask)); sigaddset(&(action_CHLD.sa_mask), SIGALRM); action_ALRM.sa_flags = SA_RESTART; action_ALRM.sa_handler = SIGALRM_handler; sigemptyset(&(action_ALRM.sa_mask)); sigaddset(&(action_ALRM.sa_mask), SIGCHLD); PointerList_Create(&apps, 0); if (NULL == apps) err_exit("PointerList_Create"); /* Command line arguments Parsing * Options * a : privileged app path * w : privileged app working directory * v : user id to use to start privileged app * h : group id to use to start privileged app * p : TCP port to receive commands * u : user id to use to start regular apps * g : group id to use to start regular apps * n : nice value (process priority) for regular apps */ char* init_app = NULL; char* init_app_wd = NULL; app_t* privileged_app = NULL; int opt; char useropt_given = 0; char grpopt_given = 0; //optarg is set by getopt while ((opt = getopt(argc, argv, "a:w:v:h:p:u:g:n:")) != -1) { switch (opt) { case 'a': init_app = optarg; SWI_LOG("APPMON", DEBUG, "Command line arguments parsing: init_app %s\n", init_app); break; case 'w': init_app_wd = optarg; SWI_LOG("APPMON", DEBUG, "Command line arguments parsing: init_app_wd %s\n", init_app_wd); break; case 'p': parse_arg_integer(optarg, &portno, "Command line arguments parsing: bad format for port argument"); SWI_LOG("APPMON", DEBUG, "Command line arguments parsing: port =%d\n", portno); if (portno > UINT16_MAX) { err_exit("Command line arguments parsing: bad value for port, range=[0, 65535]"); } break; case 'u': useropt_given = 1; //used to set default value after cmd line option parsing get_uid_option(&uid); break; case 'v': get_uid_option(&puid); break; case 'g': grpopt_given = 1; //used to set default value after cmd line option parsing get_gid_option(&gid); break; case 'h': get_gid_option(&pgid); break; case 'n': parse_arg_integer(optarg, &app_priority, "Command line arguments parsing: app process priority must be an integer"); if (19 < app_priority || -20 > app_priority) { err_exit("Command line arguments parsing: app process priority must be between -20 and 19"); } SWI_LOG("APPMON", DEBUG, "Command line arguments parsing: nice increment =%d\n", app_priority); break; default: /* '?' */ SWI_LOG("APPMON", ERROR, "Command line arguments parsing: unknown argument\n"); break; } } if (NULL != init_app) { if (NULL == init_app_wd) { //using current working directory as privileged app wd. cwd = malloc(PATH_MAX); if (NULL == cwd) { err_exit("Cannot malloc init_app_wd"); } cwd = getcwd(cwd, PATH_MAX); if (NULL == cwd) { err_exit("getcwd failed to guess privileged app default wd"); } init_app_wd = cwd; } char * res = check_params(init_app_wd, init_app); if (NULL != res) { SWI_LOG("APPMON", ERROR, "check_params on privileged app failed: %s\n", res); err_exit("check_params on privileged app failed"); } privileged_app = add_app(init_app_wd, init_app, 1); if (NULL == privileged_app) { err_exit("add_app on privileged app failed"); } } if (!uid && !useropt_given) { //get default "nobody" user. uid = 65534; } if (!gid && !grpopt_given) { //get default "nogroup" group. gid = 65534; } SWI_LOG("APPMON", DEBUG, "Command line arguments parsing: will use uid=%d and gid=%d to run unprivileged apps\n", uid, gid); /* configuring signals handling */ if (sigaction(SIGCHLD, &action_CHLD, NULL)) err_exit("configuring signals handling: sigaction SIGCHLD call error"); if (sigaction(SIGALRM, &action_ALRM, NULL)) err_exit("configuring signals handling: sigaction SIGCHLD call error"); srv_skt = socket(AF_INET, SOCK_STREAM, 0); if (srv_skt < 0) err_exit("socket configuration: opening socket error"); // set SO_REUSEADDR on socket: optval = 1; if (setsockopt(srv_skt, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval)) err_exit("socket configuration: setting SO_REUSEADDR on socket failed"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = portno ? portno : DEFAULT_LISTENING_PORT; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(srv_skt, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) err_exit("socket configuration: error on binding"); if (listen(srv_skt, 5)) err_exit("socket configuration: error on listen"); clilen = sizeof(cli_addr); stop = 0; SWI_LOG("APPMON", DEBUG, "Init successful, now running as daemon.\n"); /* daemonize the later possible to enhance sync error reporting*/ daemonize(); /* Now we are a simple daemon */ SWI_LOG("APPMON", DEBUG, "Daemon pid=%d, Listening port = %d\n", getpid(), portno); if (privileged_app) { SWI_LOG("APPMON", DEBUG, "Autostarting privileged app\n"); start_app(privileged_app); } while (!stop) { fflush(stdout); client_skt = accept(srv_skt, (struct sockaddr *) &cli_addr, &clilen); if (client_skt < 0) { SWI_LOG("APPMON", ERROR, "socket configuration: error on accept: %s\n", strerror(errno)); SWI_LOG("APPMON", ERROR, "Now going to crippled mode: cannot use socket API anymore!\n"); if (client_skt) close(client_skt); if (srv_skt) close(srv_skt); // Sleep for 1.5 sec // sleep() function not used here, as it may disrupt the use of SIGALRM made in this program. struct timeval tv; while (1) { tv.tv_sec = 1; tv.tv_usec = 0; int res = select(0, NULL, NULL, NULL, &tv); SWI_LOG("APPMON", DEBUG, "crippled mode: select, res = %d\n", res); } //never returning from here, need to kill the daemon // but apps should still be managed. } SWI_LOG("APPMON", DEBUG, "new client ...\n"); buffer = readline(client_skt); //deal with all the requests coming from the new client while (NULL != buffer && !stop) { SWI_LOG("APPMON", DEBUG, "NEW cmd=[%s]\n", buffer); do { if (!strncmp(buffer, STOP_DAEMON, strlen(STOP_DAEMON))) { stop = 1; send_result("ok, destroy is in progress, stopping aps, closing sockets."); break; } if (!strncmp(buffer, PCONFIG, strlen(PCONFIG))) { send_result( fill_output_buf( "appmon_daemon: version[%s], uid=[%d], gid=[%d], puid=[%d], pgid=[%d], app_priority=[%d]", GIT_REV, uid, gid, puid, pgid, app_priority)); break; } if (!strncmp(buffer, SETUP_APP, strlen(SETUP_APP))) { char* buf = buffer; strsep(&buf, " "); char* wd = strsep(&buf, " "); char* prog = strsep(&buf, " "); SWI_LOG("APPMON", DEBUG, "SETUP wd =%s, prog = %s\n", wd, prog); if (NULL == wd || NULL == prog) { send_result("Bad command format, must have wd and prog params"); break; } char *res = check_params(wd, prog); if (res) { send_result(res); break; } sigprocmask(SIG_BLOCK, &block_sigs, NULL); app_t* app = add_app(wd, prog, 0); if (NULL == app) send_result("Cannot add app"); else send_result(fill_output_buf("%d", app->id)); sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } if (!strncmp(buffer, START_APP, strlen(START_APP))) { char* str_id = buffer + strlen(START_APP); int id = atoi(str_id); SWI_LOG("APPMON", DEBUG, "START_APP, id =%d\n", id); if (id == 0) { send_result("Bad command format, start called with invalid app id"); break; } sigprocmask(SIG_BLOCK, &block_sigs, NULL); app_t* app = find_by_id(id); if (app == NULL) { send_result("Unknown app"); sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } if (app->privileged) { send_result("Privileged App, cannot act on it through socket."); sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } if (app->status != KILLED) { send_result("App already running (or set to be restarted), start command discarded"); sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } send_result(start_app(app)); sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } if (!strncmp(buffer, STOP_APP, strlen(STOP_APP))) { char* str_id = buffer + strlen(STOP_APP); int id = atoi(str_id); if (id == 0) { send_result("Bad command format, stop called with invalid app id"); break; } sigprocmask(SIG_BLOCK, &block_sigs, NULL); app_t* app = find_by_id(id); if (NULL == app) send_result("Unknown app"); else { if (app->privileged) { send_result("Privileged App, cannot act on it through socket."); sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } //stop command has effect only if application is running. if (app->status == STARTED || app->status == TO_BE_KILLED) { send_result(stop_app(app)); } else { //application is already stopped (app->status could be KILLED or TO_BE_RESTARTED) app->status = KILLED; //force app->status = KILLED, prevent app to be restarted if restart was scheduled. (see SIG ALRM handler) send_result("ok, already stopped, won't be automatically restarted anymore"); } } sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } if (!strncmp(buffer, REMOVE_APP, strlen(REMOVE_APP))) { char* str_id = buffer + strlen(REMOVE_APP); int id = atoi(str_id); if (id == 0) { send_result("Bad command format, remove called with invalid app id"); break; } sigprocmask(SIG_BLOCK, &block_sigs, NULL); app_t* app = find_by_id(id); if (NULL == app) send_result("Unknown app"); else { if (app->privileged) { send_result("Privileged App, cannot act on it through socket."); sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } //stop command has effect only if application is running. if (app->status == STARTED || app->status == TO_BE_KILLED) { stop_app(app); //trying to stop, no big deal with it fails } app_t* app = NULL; unsigned int size, i = 0; PointerList_GetSize(apps, &size, NULL); for (i = 0; i < size; i++) { PointerList_Peek(apps, i, (void**) &app); if (app->id == id) { swi_status_t res = 0; if (SWI_STATUS_OK != (res = PointerList_Remove(apps, i, (void**) &app))) { send_result(fill_output_buf("Remove: PointerList_Remove failed, AwtStatus =%d", res)); } else { free(app); send_result("ok"); } break; } } } sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } if (!strncmp(buffer, STATUS_APP, strlen(STATUS_APP))) { char* str_id = buffer + strlen(STATUS_APP); int id = atoi(str_id); if (id == 0) { send_result("Bad command format, status called with invalid app id"); break; } sigprocmask(SIG_BLOCK, &block_sigs, NULL); app_t* app = find_by_id(id); if (NULL == app) send_result("Unknown app"); else { SWI_LOG("APPMON", DEBUG, "sending app status...\n"); send_result(create_app_status(app)); } sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } if (!strncmp(buffer, LIST_APPS, strlen(LIST_APPS))) { SWI_LOG("APPMON", DEBUG, "sending app list ...\n"); sigprocmask(SIG_BLOCK, &block_sigs, NULL); app_t* app = NULL; unsigned int size, i = 0; PointerList_GetSize(apps, &size, NULL); for (i = 0; i < size; i++) { PointerList_Peek(apps, i, (void**) &app); char* app_status_tmp = create_app_status(app); if (strlen(app_status_tmp) != write(client_skt, app_status_tmp, strlen(app_status_tmp))) { SWI_LOG("APPMON", ERROR, "list: cannot write res to socket\n"); } SWI_LOG("APPMON", DEBUG, "list: send status, app_status_tmp=%s\n", app_status_tmp); char* statussep = "\t"; if (strlen(statussep) != write(client_skt, statussep, strlen(statussep))) { SWI_LOG("APPMON", ERROR, "list: cannot write statussep: %s\n", statussep); } } send_result(""); sigprocmask(SIG_UNBLOCK, &block_sigs, NULL); break; } if (!strncmp(buffer, SETENV, strlen(SETENV))) { char *arg, *varname, *tmp; arg = buffer + strlen(SETENV); varname = arg; tmp = strchr(arg, '='); *tmp++ = '\0'; SWI_LOG("APPMON", DEBUG, "Setting Application framework environment variable %s = %s...\n", varname, tmp); setenv(varname, tmp, 1); send_result(""); break; } //command not found send_result("command not found"); SWI_LOG("APPMON", DEBUG, "Command not found\n"); } while (0); if (stop) break; //read some data again to allow to send several commands with the same socket buffer = readline(client_skt); } //end while buffer not NULL: current client has no more data to send //current client exited, let's close client skt, wait for another connexion close(client_skt); } sigprocmask(SIG_BLOCK, &block_sigs, NULL); int exit_status_daemon = clean_all(); SWI_LOG("APPMON", DEBUG, "appmon daemon end, exit_status_daemon: %d\n", exit_status_daemon); return exit_status_daemon; }
/** * Principal */ int main(int argc, char * argv[]) { //sockfd refere-se à escuta, new_fd a novas conexoes int sockfd, new_fd; struct addrinfo hints, *servinfo, *p; //informacao de endereco dos conectores struct sockaddr_storage their_addr; socklen_t sin_size; struct sigaction sa; int yes=1; char s[INET6_ADDRSTRLEN]; int rv; int ativo; // Booleano que indica se a conexao deve continuar ativa // Vetor que contera a opcao do cliente (mais o id do filme, se for o // caso) char opt[4]; loadBooksFromDB(); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; // Stream socket hints.ai_flags = AI_PASSIVE; if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // Percorre a lista ligada e realiza 'bind' ao primeiro que for possivel // Cria todos os file descriptors dos sockets, dando nome a eles for(p = servinfo; p != NULL; p = p->ai_next) { //Função SOCKET: cria um socket, dando acesso ao serviço da camada de transporte if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) { perror("server: socket"); continue; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } //Função bind: atribui um nome ao socket if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("server: bind"); continue; } break; } // Debug de erro if (p == NULL) { fprintf(stderr, "servidor: falha ao realizar 'bind'\n"); return 2; } // Necessario devido à chamada 'getaddrinfo' acima freeaddrinfo(servinfo); // Anuncia que está apto para receber conexões if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } printf("servidor: aguardando conexoes...\n"); // Loop de aceitacao principal while(1) { sin_size = sizeof their_addr; new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); if (new_fd == -1) { // perror("accept"); continue; } inet_ntop(their_addr.ss_family,get_in_addr((struct sockaddr *)&their_addr), s, sizeof s); printf("servidor: conexao obtida de %s\n", s); // Processo filho if (!fork()) { // Processo filho nao precisa da escuta close(sockfd); ativo = 1; while(ativo){ // Recebe a opcao do client if(recv(new_fd,opt, 4, 0) == -1); perror("recv"); switch(opt[0]){ case '1': // Listar todos os Ids dos filmes com seus respectivos // titulos getAllMovieTitles(new_fd); break; case '2': // Dado o Id de um filme, retornar a sinopse getMovieSynById(new_fd, opt); break; case '3': // Dado o Id de um filme, retornar todas as informações // desse filme getMovieById(new_fd, opt); break; case '4': // Listar todas as informações de todos os filmes; getAllMovies(new_fd); break; case '5': // Finaliza conexao ativo = 0; break; default: printf("Opcao nao valida. Tente novamente\n"); break; } } close(new_fd); exit(0); } // processo pai nao precisa da nova conexao close(new_fd); } return 0; }
int main(int argc, char **argv) #endif /* WIN32 */ { #ifdef WIN32 struct arg_param *p = (struct arg_param *)pv; int argc; char **argv; SERVICE_STATUS ss; #endif /* WIN32 */ char *name = NULL; struct tpp_config conf; int rpp_fd; char *pc; int numthreads; char lockfile[MAXPATHLEN + 1]; char path_log[MAXPATHLEN + 1]; char svr_home[MAXPATHLEN + 1]; char *log_file = 0; char *host; int port; char *routers = NULL; int c, i, rc; extern char *optarg; int are_primary; int num_var_env; #ifndef WIN32 struct sigaction act; struct sigaction oact; #endif #ifndef WIN32 /*the real deal or just pbs_version and exit*/ execution_mode(argc, argv); #endif /* As a security measure and to make sure all file descriptors */ /* are available to us, close all above stderr */ #ifdef WIN32 _fcloseall(); #else i = sysconf(_SC_OPEN_MAX); while (--i > 2) (void)close(i); /* close any file desc left open by parent */ #endif /* If we are not run with real and effective uid of 0, forget it */ #ifdef WIN32 argc = p->argc; argv = p->argv; ZeroMemory(&ss, sizeof(ss)); ss.dwCheckPoint = 0; ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ss.dwCurrentState = g_dwCurrentState; ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; ss.dwWaitHint = 6000; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); if (!isAdminPrivilege(getlogin())) { fprintf(stderr, "%s: Must be run by root\n", argv[0]); return (2); } #else if ((getuid() != 0) || (geteuid() != 0)) { fprintf(stderr, "%s: Must be run by root\n", argv[0]); return (2); } #endif /* WIN32 */ /* set standard umask */ #ifndef WIN32 umask(022); #endif /* load the pbs conf file */ if (pbs_loadconf(0) == 0) { fprintf(stderr, "%s: Configuration error\n", argv[0]); return (1); } umask(022); #ifdef WIN32 save_env(); #endif /* The following is code to reduce security risks */ /* start out with standard umask, system resource limit infinite */ if ((num_var_env = setup_env(pbs_conf.pbs_environment)) == -1) { #ifdef WIN32 g_dwCurrentState = SERVICE_STOPPED; ss.dwCurrentState = g_dwCurrentState; ss.dwWin32ExitCode = ERROR_INVALID_ENVIRONMENT; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); return (1); #else exit(1); #endif /* WIN32 */ } #ifndef WIN32 i = getgid(); (void)setgroups(1, (gid_t *)&i); /* secure suppl. groups */ #endif /* set pbs_comm's process limits */ set_limits(); log_event_mask = &pbs_conf.pbs_comm_log_events; tpp_set_logmask(*log_event_mask); #ifdef WIN32 winsock_init(); #endif routers = pbs_conf.pbs_comm_routers; numthreads = pbs_conf.pbs_comm_threads; server_host[0] = '\0'; if (pbs_conf.pbs_comm_name) { name = pbs_conf.pbs_comm_name; host = tpp_parse_hostname(name, &port); if (host) snprintf(server_host, sizeof(server_host), "%s", host); free(host); host = NULL; } else if (pbs_conf.pbs_leaf_name) { name = pbs_conf.pbs_leaf_name; host = tpp_parse_hostname(name, &port); if (host) snprintf(server_host, sizeof(server_host), "%s", host); free(host); host = NULL; } else { if (gethostname(server_host, (sizeof(server_host) - 1)) == -1) { #ifndef WIN32 sprintf(log_buffer, "Could not determine my hostname, errno=%d", errno); #else sprintf(log_buffer, "Could not determine my hostname, errno=%d", WSAGetLastError()); #endif fprintf(stderr, "%s\n", log_buffer); return (1); } if ((get_fullhostname(server_host, server_host, (sizeof(server_host) - 1)) == -1)) { sprintf(log_buffer, "Could not determine my hostname"); fprintf(stderr, "%s\n", log_buffer); return (1); } name = server_host; } if (server_host[0] == '\0') { sprintf(log_buffer, "Could not determine server host"); fprintf(stderr, "%s\n", log_buffer); return (1); } while ((c = getopt(argc, argv, "r:t:e:N")) != -1) { switch (c) { case 'e': *log_event_mask = strtol(optarg, NULL, 0); break; case 'r': routers = optarg; break; case 't': numthreads = atol(optarg); if (numthreads == -1) { usage(argv[0]); return (1); } break; case 'N': stalone = 1; break; default: usage(argv[0]); return (1); } } (void)strcpy(daemonname, "Comm@"); (void)strcat(daemonname, name); if ((pc = strchr(daemonname, (int)'.')) != NULL) *pc = '\0'; if(set_msgdaemonname(daemonname)) { fprintf(stderr, "Out of memory\n"); return 1; } (void) snprintf(path_log, sizeof(path_log), "%s/%s", pbs_conf.pbs_home_path, PBS_COMM_LOGDIR); (void) log_open(log_file, path_log); /* set tcp function pointers */ set_tpp_funcs(log_tppmsg); (void) snprintf(svr_home, sizeof(svr_home), "%s/%s", pbs_conf.pbs_home_path, PBS_SVR_PRIVATE); if (chdir(svr_home) != 0) { (void) sprintf(log_buffer, msg_init_chdir, svr_home); log_err(-1, __func__, log_buffer); return (1); } (void) sprintf(lockfile, "%s/%s/comm.lock", pbs_conf.pbs_home_path, PBS_SVR_PRIVATE); if ((are_primary = are_we_primary()) == FAILOVER_SECONDARY) { strcat(lockfile, ".secondary"); } else if (are_primary == FAILOVER_CONFIG_ERROR) { sprintf(log_buffer, "Failover configuration error"); log_err(-1, __func__, log_buffer); #ifdef WIN32 g_dwCurrentState = SERVICE_STOPPED; ss.dwCurrentState = g_dwCurrentState; ss.dwWin32ExitCode = ERROR_SERVICE_NOT_ACTIVE; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); #endif return (3); } if ((lockfds = open(lockfile, O_CREAT | O_WRONLY, 0600)) < 0) { (void) sprintf(log_buffer, "pbs_comm: unable to open lock file"); log_err(errno, __func__, log_buffer); return (1); } if ((host = tpp_parse_hostname(name, &port)) == NULL) { sprintf(log_buffer, "Out of memory parsing leaf name"); log_err(errno, __func__, log_buffer); return (1); } rc = 0; if (pbs_conf.auth_method == AUTH_RESV_PORT) { rc = set_tpp_config(&pbs_conf, &conf, host, port, routers, pbs_conf.pbs_use_compression, TPP_AUTH_RESV_PORT, NULL, NULL); } else { /* for all non-resv-port based authentication use a callback from TPP */ rc = set_tpp_config(&pbs_conf, &conf, host, port, routers, pbs_conf.pbs_use_compression, TPP_AUTH_EXTERNAL, get_ext_auth_data, validate_ext_auth_data); } if (rc == -1) { (void) sprintf(log_buffer, "Error setting TPP config"); log_err(-1, __func__, log_buffer); return (1); } free(host); i = 0; if (conf.routers) { while (conf.routers[i]) { sprintf(log_buffer, "Router[%d]:%s", i, conf.routers[i]); fprintf(stdout, "%s\n", log_buffer); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_INFO, msg_daemonname, log_buffer); i++; } } #ifndef DEBUG #ifndef WIN32 if (stalone != 1) go_to_background(); #endif #endif #ifdef WIN32 ss.dwCheckPoint = 0; g_dwCurrentState = SERVICE_RUNNING; ss.dwCurrentState = g_dwCurrentState; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); #endif if (already_forked == 0) lock_out(lockfds, F_WRLCK); /* go_to_backgroud call creates a forked process, * thus print/log pid only after go_to_background() * has been called */ sprintf(log_buffer, "%s ready (pid=%d), Proxy Name:%s, Threads:%d", argv[0], getpid(), conf.node_name, numthreads); fprintf(stdout, "%s\n", log_buffer); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_INFO, msg_daemonname, log_buffer); #ifndef DEBUG pbs_close_stdfiles(); #endif #ifdef WIN32 signal(SIGINT, stop_me); signal(SIGTERM, stop_me); #else sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = hup_me; if (sigaction(SIGHUP, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for HUP"); return (2); } act.sa_handler = stop_me; if (sigaction(SIGINT, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for INT"); return (2); } if (sigaction(SIGTERM, &act, &oact) != 0) { log_err(errno, __func__, "sigactin for TERM"); return (2); } if (sigaction(SIGQUIT, &act, &oact) != 0) { log_err(errno, __func__, "sigactin for QUIT"); return (2); } #ifdef SIGSHUTDN if (sigaction(SIGSHUTDN, &act, &oact) != 0) { log_err(errno, __func__, "sigactin for SHUTDN"); return (2); } #endif /* SIGSHUTDN */ act.sa_handler = SIG_IGN; if (sigaction(SIGPIPE, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for PIPE"); return (2); } if (sigaction(SIGUSR1, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for USR1"); return (2); } if (sigaction(SIGUSR2, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for USR2"); return (2); } #endif /* WIN32 */ conf.node_type = TPP_ROUTER_NODE; conf.numthreads = numthreads; if ((rpp_fd = tpp_init_router(&conf)) == -1) { log_err(-1, __func__, "tpp init failed\n"); return 1; } /* Protect from being killed by kernel */ daemon_protect(0, PBS_DAEMON_PROTECT_ON); /* go in a while loop */ while (get_out == 0) { if (hupped == 1) { struct pbs_config pbs_conf_bak; int new_logevent; hupped = 0; /* reset back */ memcpy(&pbs_conf_bak, &pbs_conf, sizeof(struct pbs_config)); if (pbs_loadconf(1) == 0) { log_tppmsg(LOG_CRIT, NULL, "Configuration error, ignoring"); memcpy(&pbs_conf, &pbs_conf_bak, sizeof(struct pbs_config)); } else { /* restore old pbs.conf */ new_logevent = pbs_conf.pbs_comm_log_events; memcpy(&pbs_conf, &pbs_conf_bak, sizeof(struct pbs_config)); pbs_conf.pbs_comm_log_events = new_logevent; log_tppmsg(LOG_INFO, NULL, "Processed SIGHUP"); log_event_mask = &pbs_conf.pbs_comm_log_events; tpp_set_logmask(*log_event_mask); } } sleep(3); } tpp_router_shutdown(); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_NOTICE, msg_daemonname, "Exiting"); log_close(1); lock_out(lockfds, F_UNLCK); /* unlock */ (void)close(lockfds); (void)unlink(lockfile); return 0; }
void trap_init(void) { uint8_t digest[20]; struct sigaction sa, old; char path[256]; int r; memset(digest, 0, sizeof(digest)); r = readlink("/proc/self/exe", self, sizeof(self) - 1); if(r == -1) self[0] = 0; else self[r] = 0; snprintf(line1, sizeof(line1), "PRG: Showtime (%s) " "[%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x] " "EXE: %s, CWD: %s ", htsversion_full, digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15], digest[16], digest[17], digest[18], digest[19], self, getcwd(path, sizeof(path))); dl_iterate_phdr(callback, NULL); memset(&sa, 0, sizeof(sa)); sigset_t m; sigemptyset(&m); sigaddset(&m, SIGSEGV); sigaddset(&m, SIGBUS); sigaddset(&m, SIGILL); sigaddset(&m, SIGABRT); sigaddset(&m, SIGFPE); sa.sa_sigaction = traphandler; sa.sa_flags = SA_SIGINFO | SA_RESETHAND; sigaction(SIGSEGV, &sa, &old); sigaction(SIGBUS, &sa, &old); sigaction(SIGILL, &sa, &old); sigaction(SIGABRT, &sa, &old); sigaction(SIGFPE, &sa, &old); sigprocmask(SIG_UNBLOCK, &m, NULL); }
static void action_synced_wait(svc_action_t * op, sigset_t *mask) { int status = 0; int timeout = op->timeout; int sfd = -1; time_t start = -1; struct pollfd fds[3]; int wait_rc = 0; #ifdef HAVE_SYS_SIGNALFD_H sfd = signalfd(-1, mask, SFD_NONBLOCK); if (sfd < 0) { crm_perror(LOG_ERR, "signalfd() failed"); } #else sfd = sigchld_pipe[0]; #endif fds[0].fd = op->opaque->stdout_fd; fds[0].events = POLLIN; fds[0].revents = 0; fds[1].fd = op->opaque->stderr_fd; fds[1].events = POLLIN; fds[1].revents = 0; fds[2].fd = sfd; fds[2].events = POLLIN; fds[2].revents = 0; crm_trace("Waiting for %d", op->pid); start = time(NULL); do { int poll_rc = poll(fds, 3, timeout); if (poll_rc > 0) { if (fds[0].revents & POLLIN) { svc_read_output(op->opaque->stdout_fd, op, FALSE); } if (fds[1].revents & POLLIN) { svc_read_output(op->opaque->stderr_fd, op, TRUE); } if (fds[2].revents & POLLIN) { #ifdef HAVE_SYS_SIGNALFD_H struct signalfd_siginfo fdsi; ssize_t s; s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo)); if (s != sizeof(struct signalfd_siginfo)) { crm_perror(LOG_ERR, "Read from signal fd %d failed", sfd); } else if (fdsi.ssi_signo == SIGCHLD) { #else if (1) { /* Clear out the sigchld pipe. */ char ch; while (read(sfd, &ch, 1) == 1); #endif wait_rc = waitpid(op->pid, &status, WNOHANG); if (wait_rc < 0){ crm_perror(LOG_ERR, "waitpid() for %d failed", op->pid); } else if (wait_rc > 0) { break; } } } } else if (poll_rc == 0) { timeout = 0; break; } else if (poll_rc < 0) { if (errno != EINTR) { crm_perror(LOG_ERR, "poll() failed"); break; } } timeout = op->timeout - (time(NULL) - start) * 1000; } while ((op->timeout < 0 || timeout > 0)); crm_trace("Child done: %d", op->pid); if (wait_rc <= 0) { int killrc = kill(op->pid, SIGKILL); op->rc = PCMK_OCF_UNKNOWN_ERROR; if (op->timeout > 0 && timeout <= 0) { op->status = PCMK_LRM_OP_TIMEOUT; crm_warn("%s:%d - timed out after %dms", op->id, op->pid, op->timeout); } else { op->status = PCMK_LRM_OP_ERROR; } if (killrc && errno != ESRCH) { crm_err("kill(%d, KILL) failed: %d", op->pid, errno); } /* * From sigprocmask(2): * It is not possible to block SIGKILL or SIGSTOP. Attempts to do so are silently ignored. * * This makes it safe to skip WNOHANG here */ waitpid(op->pid, &status, 0); } else if (WIFEXITED(status)) { op->status = PCMK_LRM_OP_DONE; op->rc = WEXITSTATUS(status); crm_info("Managed %s process %d exited with rc=%d", op->id, op->pid, op->rc); } else if (WIFSIGNALED(status)) { int signo = WTERMSIG(status); op->status = PCMK_LRM_OP_ERROR; crm_err("Managed %s process %d exited with signal=%d", op->id, op->pid, signo); } #ifdef WCOREDUMP if (WCOREDUMP(status)) { crm_err("Managed %s process %d dumped core", op->id, op->pid); } #endif svc_read_output(op->opaque->stdout_fd, op, FALSE); svc_read_output(op->opaque->stderr_fd, op, TRUE); close(op->opaque->stdout_fd); close(op->opaque->stderr_fd); #ifdef HAVE_SYS_SIGNALFD_H close(sfd); #endif } /* For an asynchronous 'op', returns FALSE if 'op' should be free'd by the caller */ /* For a synchronous 'op', returns FALSE if 'op' fails */ gboolean services_os_action_execute(svc_action_t * op, gboolean synchronous) { int stdout_fd[2]; int stderr_fd[2]; struct stat st; sigset_t *pmask; #ifdef HAVE_SYS_SIGNALFD_H sigset_t mask; sigset_t old_mask; #define sigchld_cleanup() do { \ if (sigismember(&old_mask, SIGCHLD) == 0) { \ if (sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) { \ crm_perror(LOG_ERR, "sigprocmask() failed to unblock sigchld"); \ } \ } \ } while (0) #else struct sigaction sa; struct sigaction old_sa; #define sigchld_cleanup() do { \ if (sigaction(SIGCHLD, &old_sa, NULL) < 0) { \ crm_perror(LOG_ERR, "sigaction() failed to remove sigchld handler"); \ } \ close(sigchld_pipe[0]); \ close(sigchld_pipe[1]); \ sigchld_pipe[0] = sigchld_pipe[1] = -1; \ } while(0) #endif /* Fail fast */ if(stat(op->opaque->exec, &st) != 0) { int rc = errno; crm_warn("Cannot execute '%s': %s (%d)", op->opaque->exec, pcmk_strerror(rc), rc); services_handle_exec_error(op, rc); if (!synchronous) { return operation_finalize(op); } return FALSE; } if (pipe(stdout_fd) < 0) { int rc = errno; crm_err("pipe(stdout_fd) failed. '%s': %s (%d)", op->opaque->exec, pcmk_strerror(rc), rc); services_handle_exec_error(op, rc); if (!synchronous) { return operation_finalize(op); } return FALSE; } if (pipe(stderr_fd) < 0) { int rc = errno; close(stdout_fd[0]); close(stdout_fd[1]); crm_err("pipe(stderr_fd) failed. '%s': %s (%d)", op->opaque->exec, pcmk_strerror(rc), rc); services_handle_exec_error(op, rc); if (!synchronous) { return operation_finalize(op); } return FALSE; } if (synchronous) { #ifdef HAVE_SYS_SIGNALFD_H sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigemptyset(&old_mask); if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0) { crm_perror(LOG_ERR, "sigprocmask() failed to block sigchld"); } pmask = &mask; #else if(pipe(sigchld_pipe) == -1) { crm_perror(LOG_ERR, "pipe() failed"); } set_fd_opts(sigchld_pipe[0], O_NONBLOCK); set_fd_opts(sigchld_pipe[1], O_NONBLOCK); sa.sa_handler = sigchld_handler; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); if (sigaction(SIGCHLD, &sa, &old_sa) < 0) { crm_perror(LOG_ERR, "sigaction() failed to set sigchld handler"); } pmask = NULL; #endif } op->pid = fork(); switch (op->pid) { case -1: { int rc = errno; close(stdout_fd[0]); close(stdout_fd[1]); close(stderr_fd[0]); close(stderr_fd[1]); crm_err("Could not execute '%s': %s (%d)", op->opaque->exec, pcmk_strerror(rc), rc); services_handle_exec_error(op, rc); if (!synchronous) { return operation_finalize(op); } sigchld_cleanup(); return FALSE; } case 0: /* Child */ close(stdout_fd[0]); close(stderr_fd[0]); if (STDOUT_FILENO != stdout_fd[1]) { if (dup2(stdout_fd[1], STDOUT_FILENO) != STDOUT_FILENO) { crm_err("dup2() failed (stdout)"); } close(stdout_fd[1]); } if (STDERR_FILENO != stderr_fd[1]) { if (dup2(stderr_fd[1], STDERR_FILENO) != STDERR_FILENO) { crm_err("dup2() failed (stderr)"); } close(stderr_fd[1]); } if (synchronous) { sigchld_cleanup(); } action_launch_child(op); CRM_ASSERT(0); /* action_launch_child is effectively noreturn */ } /* Only the parent reaches here */ close(stdout_fd[1]); close(stderr_fd[1]); op->opaque->stdout_fd = stdout_fd[0]; set_fd_opts(op->opaque->stdout_fd, O_NONBLOCK); op->opaque->stderr_fd = stderr_fd[0]; set_fd_opts(op->opaque->stderr_fd, O_NONBLOCK); if (synchronous) { action_synced_wait(op, pmask); sigchld_cleanup(); } else { crm_trace("Async waiting for %d - %s", op->pid, op->opaque->exec); mainloop_child_add_with_flags(op->pid, op->timeout, op->id, op, (op->flags & SVC_ACTION_LEAVE_GROUP) ? mainloop_leave_pid_group : 0, operation_finished); op->opaque->stdout_gsource = mainloop_add_fd(op->id, G_PRIORITY_LOW, op->opaque->stdout_fd, op, &stdout_callbacks); op->opaque->stderr_gsource = mainloop_add_fd(op->id, G_PRIORITY_LOW, op->opaque->stderr_fd, op, &stderr_callbacks); services_add_inflight_op(op); } return TRUE; }
int main(int argc, char *argv[]) { char *conf_filename; int result; int sock; int wait_count; pthread_t schedule_tid; struct sigaction act; ScheduleEntry scheduleEntries[SCHEDULE_ENTRIES_MAX_COUNT]; ScheduleArray scheduleArray; char pidFilename[MAX_PATH_SIZE]; bool stop; if (argc < 2) { usage(argv[0]); return 1; } g_current_time = time(NULL); g_up_time = g_current_time; log_init2(); trunk_shared_init(); conf_filename = argv[1]; if ((result=get_base_path_from_conf_file(conf_filename, g_fdfs_base_path, sizeof(g_fdfs_base_path))) != 0) { log_destroy(); return result; } snprintf(pidFilename, sizeof(pidFilename), "%s/data/fdfs_storaged.pid", g_fdfs_base_path); if ((result=process_action(pidFilename, argv[2], &stop)) != 0) { if (result == EINVAL) { usage(argv[0]); } log_destroy(); return result; } if (stop) { log_destroy(); return 0; } #if defined(DEBUG_FLAG) && defined(OS_LINUX) if (getExeAbsoluteFilename(argv[0], g_exe_name, \ sizeof(g_exe_name)) == NULL) { logCrit("exit abnormally!\n"); log_destroy(); return errno != 0 ? errno : ENOENT; } #endif memset(g_bind_addr, 0, sizeof(g_bind_addr)); if ((result=storage_func_init(conf_filename, \ g_bind_addr, sizeof(g_bind_addr))) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } sock = socketServer(g_bind_addr, g_server_port, &result); if (sock < 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } if ((result=tcpsetserveropt(sock, g_fdfs_network_timeout)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } daemon_init(false); umask(0); if ((result=write_to_pid_file(pidFilename)) != 0) { log_destroy(); return result; } if ((result=storage_sync_init()) != 0) { logCrit("file: "__FILE__", line: %d, " \ "storage_sync_init fail, program exit!", __LINE__); g_continue_flag = false; return result; } if ((result=tracker_report_init()) != 0) { logCrit("file: "__FILE__", line: %d, " \ "tracker_report_init fail, program exit!", __LINE__); g_continue_flag = false; return result; } if ((result=storage_service_init()) != 0) { logCrit("file: "__FILE__", line: %d, " \ "storage_service_init fail, program exit!", __LINE__); g_continue_flag = false; return result; } if ((result=set_rand_seed()) != 0) { logCrit("file: "__FILE__", line: %d, " \ "set_rand_seed fail, program exit!", __LINE__); g_continue_flag = false; return result; } memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = sigUsrHandler; if(sigaction(SIGUSR1, &act, NULL) < 0 || \ sigaction(SIGUSR2, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } act.sa_handler = sigHupHandler; if(sigaction(SIGHUP, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } act.sa_handler = SIG_IGN; if(sigaction(SIGPIPE, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } act.sa_handler = sigQuitHandler; if(sigaction(SIGINT, &act, NULL) < 0 || \ sigaction(SIGTERM, &act, NULL) < 0 || \ sigaction(SIGQUIT, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } #if defined(DEBUG_FLAG) /* #if defined(OS_LINUX) memset(&act, 0, sizeof(act)); act.sa_sigaction = sigSegvHandler; act.sa_flags = SA_SIGINFO; if (sigaction(SIGSEGV, &act, NULL) < 0 || \ sigaction(SIGABRT, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } #endif */ memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = sigDumpHandler; if(sigaction(SIGUSR1, &act, NULL) < 0 || \ sigaction(SIGUSR2, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } #endif #ifdef WITH_HTTPD if (!g_http_params.disabled) { if ((result=storage_httpd_start(g_bind_addr)) != 0) { logCrit("file: "__FILE__", line: %d, " \ "storage_httpd_start fail, " \ "program exit!", __LINE__); return result; } } #endif if ((result=tracker_report_thread_start()) != 0) { logCrit("file: "__FILE__", line: %d, " \ "tracker_report_thread_start fail, " \ "program exit!", __LINE__); g_continue_flag = false; storage_func_destroy(); log_destroy(); return result; } scheduleArray.entries = scheduleEntries; memset(scheduleEntries, 0, sizeof(scheduleEntries)); scheduleEntries[0].id = 1; scheduleEntries[0].time_base.hour = TIME_NONE; scheduleEntries[0].time_base.minute = TIME_NONE; scheduleEntries[0].time_base.second = TIME_NONE; scheduleEntries[0].interval = g_sync_log_buff_interval; scheduleEntries[0].task_func = log_sync_func; scheduleEntries[0].func_args = &g_log_context; scheduleEntries[1].id = 2; scheduleEntries[1].time_base.hour = TIME_NONE; scheduleEntries[1].time_base.minute = TIME_NONE; scheduleEntries[1].time_base.second = TIME_NONE; scheduleEntries[1].interval = g_sync_binlog_buff_interval; scheduleEntries[1].task_func = fdfs_binlog_sync_func; scheduleEntries[1].func_args = NULL; scheduleEntries[2].id = 3; scheduleEntries[2].time_base.hour = TIME_NONE; scheduleEntries[2].time_base.minute = TIME_NONE; scheduleEntries[2].time_base.second = TIME_NONE; scheduleEntries[2].interval = g_sync_stat_file_interval; scheduleEntries[2].task_func = fdfs_stat_file_sync_func; scheduleEntries[2].func_args = NULL; scheduleArray.count = 3; if (g_if_use_trunk_file) { scheduleEntries[scheduleArray.count].id = 4; scheduleEntries[scheduleArray.count].time_base.hour = TIME_NONE; scheduleEntries[scheduleArray.count].time_base.minute=TIME_NONE; scheduleEntries[scheduleArray.count].time_base.second=TIME_NONE; scheduleEntries[scheduleArray.count].interval = 1; scheduleEntries[scheduleArray.count].task_func = \ trunk_binlog_sync_func; scheduleEntries[scheduleArray.count].func_args = NULL; scheduleArray.count++; } if (g_use_access_log) { scheduleEntries[scheduleArray.count].id = 5; scheduleEntries[scheduleArray.count].time_base.hour = TIME_NONE; scheduleEntries[scheduleArray.count].time_base.minute=TIME_NONE; scheduleEntries[scheduleArray.count].time_base.second=TIME_NONE; scheduleEntries[scheduleArray.count].interval = \ g_sync_log_buff_interval; scheduleEntries[scheduleArray.count].task_func = log_sync_func; scheduleEntries[scheduleArray.count].func_args = \ &g_access_log_context; scheduleArray.count++; if (g_rotate_access_log) { scheduleEntries[scheduleArray.count].id = 6; scheduleEntries[scheduleArray.count].time_base = \ g_access_log_rotate_time; scheduleEntries[scheduleArray.count].interval = \ 24 * 3600; scheduleEntries[scheduleArray.count].task_func = \ log_notify_rotate; scheduleEntries[scheduleArray.count].func_args = \ &g_access_log_context; scheduleArray.count++; if (g_log_file_keep_days > 0) { log_set_keep_days(&g_access_log_context, g_log_file_keep_days); scheduleEntries[scheduleArray.count].id = 7; scheduleEntries[scheduleArray.count].time_base.hour = 1; scheduleEntries[scheduleArray.count].time_base.minute = 0; scheduleEntries[scheduleArray.count].time_base.second = 0; scheduleEntries[scheduleArray.count].interval = 24 * 3600; scheduleEntries[scheduleArray.count].task_func = log_delete_old_files; scheduleEntries[scheduleArray.count].func_args = &g_access_log_context; scheduleArray.count++; } } } if (g_rotate_error_log) { scheduleEntries[scheduleArray.count].id = 8; scheduleEntries[scheduleArray.count].time_base = \ g_error_log_rotate_time; scheduleEntries[scheduleArray.count].interval = \ 24 * 3600; scheduleEntries[scheduleArray.count].task_func = \ log_notify_rotate; scheduleEntries[scheduleArray.count].func_args = \ &g_log_context; scheduleArray.count++; if (g_log_file_keep_days > 0) { log_set_keep_days(&g_log_context, g_log_file_keep_days); scheduleEntries[scheduleArray.count].id = 9; scheduleEntries[scheduleArray.count].time_base.hour = 1; scheduleEntries[scheduleArray.count].time_base.minute = 0; scheduleEntries[scheduleArray.count].time_base.second = 0; scheduleEntries[scheduleArray.count].interval = 24 * 3600; scheduleEntries[scheduleArray.count].task_func = log_delete_old_files; scheduleEntries[scheduleArray.count].func_args = &g_log_context; scheduleArray.count++; } } if ((result=sched_start(&scheduleArray, &schedule_tid, \ g_thread_stack_size, (bool * volatile)&g_continue_flag)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } if ((result=set_run_by(g_run_by_group, g_run_by_user)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } if ((result=storage_dio_init()) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } log_set_cache(true); bTerminateFlag = false; bAcceptEndFlag = false; storage_accept_loop(sock); bAcceptEndFlag = true; fdfs_binlog_sync_func(NULL); //binlog fsync if (g_schedule_flag) { pthread_kill(schedule_tid, SIGINT); } storage_terminate_threads(); storage_dio_terminate(); kill_tracker_report_threads(); kill_storage_sync_threads(); wait_count = 0; while (g_storage_thread_count != 0 || \ g_dio_thread_count != 0 || \ g_tracker_reporter_count > 0 || \ g_schedule_flag) { /* #if defined(DEBUG_FLAG) && defined(OS_LINUX) if (bSegmentFault) { sleep(5); break; } #endif */ usleep(10000); if (++wait_count > 6000) { logWarning("waiting timeout, exit!"); break; } } tracker_report_destroy(); storage_service_destroy(); storage_sync_destroy(); storage_func_destroy(); if (g_if_use_trunk_file) { trunk_sync_destroy(); storage_trunk_destroy(); } logInfo("exit normally.\n"); log_destroy(); delete_pid_file(pidFilename); return 0; }
int main() { int p,i; int pid,statval; char snumproc[5],soml[12],stcpu[5],stes[5]; struct itimerval itimer; struct itimerval otimer; struct sigaction act; // Obtener los ciclos por tiempo sprintf(soml,"%d",(int) get_one_millisec_loop()); printf("%s\n",soml); // Crear semáforo para asegurarse que solo 1 proceso pueda ejecutar handler // non_reentrant=semget((key_t)5234, 1, 0666 | IPC_CREAT); // set_semvalue(1,non_reentrant); // Crear pipe para que el scheduller sepa cual proceso terminó E/S unlink("fifo0"); mkfifo("fifo0",0777); fp=fopen("fifo0","r+"); // Pedir los datos de entrada al usuario for(p=0;p<MAXPROC;p++) { printf("Proceso %d\n",p); printf(" Tiempo de llegada ....................... : "); scanf("%d",&proceso[p].tinicio); printf(" Tiempo de cpu ........................... : "); scanf("%d",&proceso[p].tcpu); printf(" Tiempo de entrada y salida .............. : "); scanf("%d",&proceso[p].tes); printf(" Prioridad (usar solo para fixed priority) : "); scanf("%d",&proceso[p].prioridad); tiempo_total+=proceso[p].tcpu; proceso[p].trestante=proceso[p].tcpu; proceso[p].estado=NUEVO; } // Crear los procesos for(p=0;p<MAXPROC;p++) { proceso[p].pid=fork(); if(proceso[p].pid==0) { kill(getpid(),SIGSTOP); //SIGSTOP:pause SIGCONT:continue process sprintf(snumproc,"%d",p); sprintf(stcpu,"%d",proceso[p].tcpu); sprintf(stes,"%d",proceso[p].tes); execlp("./proceso","proceso",snumproc,soml,stcpu,stes,NULL); } } printf("Proceso %d\n",getpid()); // Establece el handler para manejar las señales act.sa_handler=handler; sigaddset(&act.sa_mask,SIGALRM); sigaddset(&act.sa_mask,SIGUSR1); sigaddset(&act.sa_mask,SIGUSR2); act.sa_flags=SA_RESTART; sigaction(SIGALRM,&act,0);//signal inicializa new process act.sa_handler=handler; sigaddset(&act.sa_mask,SIGALRM); sigaddset(&act.sa_mask,SIGUSR1); sigaddset(&act.sa_mask,SIGUSR2); act.sa_flags=SA_RESTART; sigaction(SIGUSR1,&act,0); //signal solicita entrada y salida act.sa_handler=handler; sigaddset(&act.sa_mask,SIGALRM); sigaddset(&act.sa_mask,SIGUSR1); sigaddset(&act.sa_mask,SIGUSR2); act.sa_flags=SA_RESTART; sigaction(SIGUSR2,&act,0); //signal termina entrada y salida // Inicializa variables listos.ent=0; listos.sal=0; bloqueados.ent=0; bloqueados.sal=0; proceso_en_ejecucion=NINGUNO; // Inicia el timer itimer.it_interval.tv_sec=1;//quantum =1seg itimer.it_interval.tv_usec=0;//quantum +=0micros itimer.it_value.tv_sec=1; itimer.it_value.tv_usec=0; if(setitimer(ITIMER_REAL,&itimer,&otimer)<0) perror("Error en el settimer"); // Aquà vamos a esperar a los procesos for(p=0;p<MAXPROC;p++) { pid=wait(&statval); for(i=0;i<MAXPROC;i++) if(proceso[i].pid==pid) //checa que proceso fue el que termino { proceso_terminado=i; //setea el proceso terminado handler(SIGCHLD); //manda señal para avisar que este ha terminado } } // del_semvalue(non_reentrant); fclose(fp); exit(EXIT_SUCCESS); }
static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle) { ngx_uint_t m, i; ngx_event_t *rev, *wev; ngx_listening_t *ls; ngx_connection_t *c, *next, *old; ngx_core_conf_t *ccf; ngx_event_conf_t *ecf; ngx_event_module_t *module; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module); if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) { ngx_use_accept_mutex = 1; ngx_accept_mutex_held = 0; ngx_accept_mutex_delay = ecf->accept_mutex_delay; } else { ngx_use_accept_mutex = 0; } #if (NGX_WIN32) /* * disable accept mutex on win32 as it may cause deadlock if * grabbed by a process which can't accept connections */ ngx_use_accept_mutex = 0; #endif ngx_queue_init(&ngx_posted_accept_events); ngx_queue_init(&ngx_posted_events); if (ngx_event_timer_init(cycle->log) == NGX_ERROR) { return NGX_ERROR; } for (m = 0; cycle->modules[m]; m++) { if (cycle->modules[m]->type != NGX_EVENT_MODULE) { continue; } if (cycle->modules[m]->ctx_index != ecf->use) { continue; } module = cycle->modules[m]->ctx; if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) { /* fatal */ exit(2); } break; } #if !(NGX_WIN32) if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) { struct sigaction sa; struct itimerval itv; ngx_memzero(&sa, sizeof(struct sigaction)); sa.sa_handler = ngx_timer_signal_handler; sigemptyset(&sa.sa_mask); if (sigaction(SIGALRM, &sa, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigaction(SIGALRM) failed"); return NGX_ERROR; } itv.it_interval.tv_sec = ngx_timer_resolution / 1000; itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000; itv.it_value.tv_sec = ngx_timer_resolution / 1000; itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000; if (setitimer(ITIMER_REAL, &itv, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setitimer() failed"); } } if (ngx_event_flags & NGX_USE_FD_EVENT) { struct rlimit rlmt; if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "getrlimit(RLIMIT_NOFILE) failed"); return NGX_ERROR; } cycle->files_n = (ngx_uint_t) rlmt.rlim_cur; cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n, cycle->log); if (cycle->files == NULL) { return NGX_ERROR; } } #else if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) { ngx_log_error(NGX_LOG_WARN, cycle->log, 0, "the \"timer_resolution\" directive is not supported " "with the configured event method, ignored"); ngx_timer_resolution = 0; } #endif cycle->connections = ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log); if (cycle->connections == NULL) { return NGX_ERROR; } c = cycle->connections; cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n, cycle->log); if (cycle->read_events == NULL) { return NGX_ERROR; } rev = cycle->read_events; for (i = 0; i < cycle->connection_n; i++) { rev[i].closed = 1; rev[i].instance = 1; } cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n, cycle->log); if (cycle->write_events == NULL) { return NGX_ERROR; } wev = cycle->write_events; for (i = 0; i < cycle->connection_n; i++) { wev[i].closed = 1; } i = cycle->connection_n; next = NULL; do { i--; c[i].data = next; c[i].read = &cycle->read_events[i]; c[i].write = &cycle->write_events[i]; c[i].fd = (ngx_socket_t) -1; next = &c[i]; } while (i); cycle->free_connections = next; cycle->free_connection_n = cycle->connection_n; /* for each listening socket */ ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { #if (NGX_HAVE_REUSEPORT) if (ls[i].reuseport && ls[i].worker != ngx_worker) { continue; } #endif c = ngx_get_connection(ls[i].fd, cycle->log); if (c == NULL) { return NGX_ERROR; } c->log = &ls[i].log; c->listening = &ls[i]; ls[i].connection = c; rev = c->read; rev->log = c->log; rev->accept = 1; #if (NGX_HAVE_DEFERRED_ACCEPT) rev->deferred_accept = ls[i].deferred_accept; #endif if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { if (ls[i].previous) { /* * delete the old accept events that were bound to * the old cycle read events array */ old = ls[i].previous->connection; if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT) == NGX_ERROR) { return NGX_ERROR; } old->fd = (ngx_socket_t) -1; } } #if (NGX_WIN32) if (ngx_event_flags & NGX_USE_IOCP_EVENT) { ngx_iocp_conf_t *iocpcf; rev->handler = ngx_event_acceptex; if (ngx_use_accept_mutex) { continue; } if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) { return NGX_ERROR; } ls[i].log.handler = ngx_acceptex_log_error; iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module); if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex) == NGX_ERROR) { return NGX_ERROR; } } else { rev->handler = ngx_event_accept; if (ngx_use_accept_mutex) { continue; } if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { return NGX_ERROR; } } #else rev->handler = ngx_event_accept; if (ngx_use_accept_mutex #if (NGX_HAVE_REUSEPORT) && !ls[i].reuseport #endif ) { continue; } if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { return NGX_ERROR; } #endif } return NGX_OK; }
int main(int argc, char **argv) { struct sigaction sa; struct netconfig *nconf; void *nc_handle; in_port_t svcport; int ch, i, s; char *endptr, **hosts_bak; int have_v6 = 1; int maxrec = RPC_MAXDATASIZE; int attempt_cnt, port_len, port_pos, ret; char **port_list; while ((ch = getopt(argc, argv, "dh:p:")) != -1) switch (ch) { case 'd': debug = 1; break; case 'h': ++nhosts; hosts_bak = hosts; hosts_bak = realloc(hosts, nhosts * sizeof(char *)); if (hosts_bak == NULL) { if (hosts != NULL) { for (i = 0; i < nhosts; i++) free(hosts[i]); free(hosts); out_of_mem(); } } hosts = hosts_bak; hosts[nhosts - 1] = strdup(optarg); if (hosts[nhosts - 1] == NULL) { for (i = 0; i < (nhosts - 1); i++) free(hosts[i]); free(hosts); out_of_mem(); } break; case 'p': endptr = NULL; svcport = (in_port_t)strtoul(optarg, &endptr, 10); if (endptr == NULL || *endptr != '\0' || svcport == 0 || svcport >= IPPORT_MAX) usage(); svcport_str = strdup(optarg); break; default: usage(); } argc -= optind; argv += optind; (void)rpcb_unset(SM_PROG, SM_VERS, NULL); /* * Check if IPv6 support is present. */ s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (s < 0) have_v6 = 0; else close(s); rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); /* * If no hosts were specified, add a wildcard entry to bind to * INADDR_ANY. Otherwise make sure 127.0.0.1 and ::1 are added to the * list. */ if (nhosts == 0) { hosts = malloc(sizeof(char**)); if (hosts == NULL) out_of_mem(); hosts[0] = "*"; nhosts = 1; } else { hosts_bak = hosts; if (have_v6) { hosts_bak = realloc(hosts, (nhosts + 2) * sizeof(char *)); if (hosts_bak == NULL) { for (i = 0; i < nhosts; i++) free(hosts[i]); free(hosts); out_of_mem(); } else hosts = hosts_bak; nhosts += 2; hosts[nhosts - 2] = "::1"; } else { hosts_bak = realloc(hosts, (nhosts + 1) * sizeof(char *)); if (hosts_bak == NULL) { for (i = 0; i < nhosts; i++) free(hosts[i]); free(hosts); out_of_mem(); } else { nhosts += 1; hosts = hosts_bak; } } hosts[nhosts - 1] = "127.0.0.1"; } attempt_cnt = 1; sock_fdcnt = 0; sock_fd = NULL; port_list = NULL; port_len = 0; nc_handle = setnetconfig(); while ((nconf = getnetconfig(nc_handle))) { /* We want to listen only on udp6, tcp6, udp, tcp transports */ if (nconf->nc_flag & NC_VISIBLE) { /* Skip if there's no IPv6 support */ if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) { /* DO NOTHING */ } else { ret = create_service(nconf); if (ret == 1) /* Ignore this call */ continue; if (ret < 0) { /* * Failed to bind port, so close off * all sockets created and try again * if the port# was dynamically * assigned via bind(2). */ clearout_service(); if (mallocd_svcport != 0 && attempt_cnt < GETPORT_MAXTRY) { free(svcport_str); svcport_str = NULL; mallocd_svcport = 0; } else { errno = EADDRINUSE; syslog(LOG_ERR, "bindresvport_sa: %m"); exit(1); } /* Start over at the first service. */ free(sock_fd); sock_fdcnt = 0; sock_fd = NULL; nc_handle = setnetconfig(); attempt_cnt++; } else if (mallocd_svcport != 0 && attempt_cnt == GETPORT_MAXTRY) { /* * For the last attempt, allow * different port #s for each nconf * by saving the svcport_str and * setting it back to NULL. */ port_list = realloc(port_list, (port_len + 1) * sizeof(char *)); if (port_list == NULL) out_of_mem(); port_list[port_len++] = svcport_str; svcport_str = NULL; mallocd_svcport = 0; } } } } /* * Successfully bound the ports, so call complete_service() to * do the rest of the setup on the service(s). */ sock_fdpos = 0; port_pos = 0; nc_handle = setnetconfig(); while ((nconf = getnetconfig(nc_handle))) { /* We want to listen only on udp6, tcp6, udp, tcp transports */ if (nconf->nc_flag & NC_VISIBLE) { /* Skip if there's no IPv6 support */ if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) { /* DO NOTHING */ } else if (port_list != NULL) { if (port_pos >= port_len) { syslog(LOG_ERR, "too many port#s"); exit(1); } complete_service(nconf, port_list[port_pos++]); } else complete_service(nconf, svcport_str); } } endnetconfig(nc_handle); free(sock_fd); if (port_list != NULL) { for (port_pos = 0; port_pos < port_len; port_pos++) free(port_list[port_pos]); free(port_list); } init_file("/var/db/statd.status"); /* Note that it is NOT sensible to run this program from inetd - the */ /* protocol assumes that it will run immediately at boot time. */ daemon(0, 0); openlog("rpc.statd", 0, LOG_DAEMON); if (debug) syslog(LOG_INFO, "Starting - debug enabled"); else syslog(LOG_INFO, "Starting"); /* Install signal handler to collect exit status of child processes */ sa.sa_handler = handle_sigchld; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGCHLD); sa.sa_flags = SA_RESTART; sigaction(SIGCHLD, &sa, NULL); /* Initialisation now complete - start operating */ notify_hosts(); /* Forks a process (if necessary) to do the */ /* SM_NOTIFY calls, which may be slow. */ svc_run(); /* Should never return */ exit(1); }
int main() { char mqname[NAMESIZE], msgrv[BUFFER]; mqd_t mqdes; struct timespec ts; time_t oldtime, newtime; struct mq_attr attr; pid_t pid; int unresolved = 0, failure = 0; sprintf(mqname, "/" FUNCTION "_" TEST "_%d", getpid()); attr.mq_msgsize = BUFFER; attr.mq_maxmsg = BUFFER; mqdes = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); if (mqdes == (mqd_t)-1) { perror(ERROR_PREFIX "mq_open"); unresolved = 1; } pid = fork(); if (pid != 0) { /* Parent process */ struct sigaction act; act.sa_handler = exit_handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGABRT, &act, 0); #ifdef _POSIX_TIMERS printf("Using CLOCK_REALTIME\n"); clock_gettime(CLOCK_REALTIME, &ts); oldtime = ts.tv_sec; ts.tv_sec = ts.tv_sec + TIMEOUT; #else ts.tv_sec = time(NULL) + TIMEOUT; oldtime = time(NULL); #endif ts.tv_nsec = 0; mq_timedreceive(mqdes, msgrv, BUFFER, NULL, &ts); #ifdef _POSIX_TIMERS clock_gettime(CLOCK_REALTIME, &ts); newtime = ts.tv_sec; #else newtime = time(NULL); #endif if ((newtime - oldtime) < TIMEOUT) { printf("FAIL: mq_timedreceive didn't block until " "timout expires\n"); failure = 1; } /* Parent is not blocking, let child abort */ kill(pid, SIGABRT); wait(NULL); if (mq_close(mqdes) != 0) { perror(ERROR_PREFIX "mq_close"); unresolved = 1; } if (mq_unlink(mqname) != 0) { perror(ERROR_PREFIX "mq_unlink"); unresolved = 1; } if (failure == 1 || blocking == 1) { printf("Test FAILED\n"); return PTS_FAIL; } if (unresolved == 1) { printf("Test UNRESOLVED\n"); return PTS_UNRESOLVED; } printf("Test PASSED\n"); return PTS_PASS; } else { sleep(TIMEOUT + 3); /* Parent is probably blocking send a signal to let it abort */ kill(getppid(), SIGABRT); return 0; } }
/* * stress_socket_server() * server writer */ static int stress_socket_server( uint64_t *const counter, const uint32_t instance, const uint64_t max_ops, const char *name, const pid_t pid, const pid_t ppid) { char buf[SOCKET_BUF]; int fd, status; int so_reuseaddr = 1; struct sigaction new_action; socklen_t addr_len = 0; struct sockaddr *addr; uint64_t msgs = 0; int rc = EXIT_SUCCESS; setpgid(pid, pgrp); new_action.sa_handler = handle_socket_sigalrm; sigemptyset(&new_action.sa_mask); new_action.sa_flags = 0; if (sigaction(SIGALRM, &new_action, NULL) < 0) { pr_fail_err(name, "sigaction"); rc = EXIT_FAILURE; goto die; } if ((fd = socket(opt_socket_domain, SOCK_STREAM, 0)) < 0) { pr_fail_dbg(name, "socket"); rc = EXIT_FAILURE; goto die; } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr, sizeof(so_reuseaddr)) < 0) { pr_fail_dbg(name, "setsockopt"); rc = EXIT_FAILURE; goto die_close; } stress_set_sockaddr(name, instance, ppid, opt_socket_domain, opt_socket_port, &addr, &addr_len); if (bind(fd, addr, addr_len) < 0) { pr_fail_dbg(name, "bind"); rc = EXIT_FAILURE; goto die_close; } if (listen(fd, 10) < 0) { pr_fail_dbg(name, "listen"); rc = EXIT_FAILURE; goto die_close; } do { int sfd = accept(fd, (struct sockaddr *)NULL, NULL); if (sfd >= 0) { size_t i, j; struct sockaddr addr; socklen_t len; int sndbuf; struct msghdr msg; struct iovec vec[sizeof(buf)/16]; #if defined(HAVE_SENDMMSG) struct mmsghdr msgvec[MSGVEC_SIZE]; unsigned int msg_len = 0; #endif #if defined(SOCKET_NODELAY) int one = 1; #endif len = sizeof(addr); if (getsockname(fd, &addr, &len) < 0) { pr_fail_dbg(name, "getsockname"); (void)close(sfd); break; } len = sizeof(sndbuf); if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, &len) < 0) { pr_fail_dbg(name, "getsockopt"); (void)close(sfd); break; } #if defined(SOCKET_NODELAY) if (opt_flags & OPT_FLAGS_SOCKET_NODELAY) { if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) { pr_inf(stderr, "%s: setsockopt TCP_NODELAY " "failed and disabled, errno=%d (%s)\n", name, errno, strerror(errno)); opt_flags &= ~OPT_FLAGS_SOCKET_NODELAY; } } #endif memset(buf, 'A' + (*counter % 26), sizeof(buf)); switch (opt_socket_opts) { case SOCKET_OPT_SEND: for (i = 16; i < sizeof(buf); i += 16) { ssize_t ret = send(sfd, buf, i, 0); if (ret < 0) { if (errno != EINTR) pr_fail_dbg(name, "send"); break; } else msgs++; } break; case SOCKET_OPT_SENDMSG: for (j = 0, i = 16; i < sizeof(buf); i += 16, j++) { vec[j].iov_base = buf; vec[j].iov_len = i; } memset(&msg, 0, sizeof(msg)); msg.msg_iov = vec; msg.msg_iovlen = j; if (sendmsg(sfd, &msg, 0) < 0) { if (errno != EINTR) pr_fail_dbg(name, "sendmsg"); } else msgs += j; break; #if defined(HAVE_SENDMMSG) case SOCKET_OPT_SENDMMSG: memset(msgvec, 0, sizeof(msgvec)); for (j = 0, i = 16; i < sizeof(buf); i += 16, j++) { vec[j].iov_base = buf; vec[j].iov_len = i; msg_len += i; } for (i = 0; i < MSGVEC_SIZE; i++) { msgvec[i].msg_hdr.msg_iov = vec; msgvec[i].msg_hdr.msg_iovlen = j; } if (sendmmsg(sfd, msgvec, MSGVEC_SIZE, 0) < 0) { if (errno != EINTR) pr_fail_dbg(name, "sendmmsg"); } else msgs += (MSGVEC_SIZE * j); break; #endif default: /* Should never happen */ pr_err(stderr, "%s: bad option %d\n", name, opt_socket_opts); (void)close(sfd); goto die_close; } if (getpeername(sfd, &addr, &len) < 0) { pr_fail_dbg(name, "getpeername"); } (void)close(sfd); } (*counter)++; } while (opt_do_run && (!max_ops || *counter < max_ops)); die_close: (void)close(fd); die: #ifdef AF_UNIX if (opt_socket_domain == AF_UNIX) { struct sockaddr_un *addr_un = (struct sockaddr_un *)addr; (void)unlink(addr_un->sun_path); } #endif if (pid) { (void)kill(pid, SIGKILL); (void)waitpid(pid, &status, 0); } pr_dbg(stderr, "%s: %" PRIu64 " messages sent\n", name, msgs); return rc; }
int main(int argc, char *argv[]) { int num_cpus, test_num, len; /* Total time = TIME_INTERVAL*num_cpus */ char mygroup[FILENAME_MAX], mytaskfile[FILENAME_MAX]; char mysharesfile[FILENAME_MAX], ch; pid_t pid; int my_group_num; /* A number attached with a group */ int fd; /* To open a fifo for synchronization */ int first_counter = 0; /* To take n number of readings */ int second_counter = 0; /* no of times shares have changed */ double total_cpu_time; /* Accumulated cpu time */ double delta_cpu_time; /* Time the task could run on cpu(s) */ double prev_cpu_time = 0; double exp_cpu_time; /* Exp time in % by shares calculation */ struct rusage cpu_usage; time_t current_time, prev_time, delta_time; unsigned long int myshares = 2, baseshares = 1000; unsigned int fmyshares, num_tasks; struct sigaction newaction, oldaction; num_cpus = 0; test_num = 0; my_group_num = -1; /* Signal handling for alarm */ sigemptyset(&newaction.sa_mask); newaction.sa_handler = signal_handler_alarm; newaction.sa_flags = 0; sigaction(SIGALRM, &newaction, &oldaction); /* Check if all parameters passed are correct */ if ((argc < 5) || ((my_group_num = atoi(argv[1])) <= 0) || ((scriptpid = atoi(argv[3])) <= 0) || ((num_cpus = atoi(argv[4])) <= 0) || (test_num = atoi(argv[5])) <= 0) tst_brkm(TBROK, cleanup, "Invalid input parameters\n"); if (test_num == 1) myshares *= my_group_num; else if (test_num == 3) myshares = baseshares; else tst_brkm(TBROK, cleanup, "Wrong Test num passed. Exiting.\n"); sprintf(mygroup, "%s", argv[2]); sprintf(mytaskfile, "%s", mygroup); sprintf(mysharesfile, "%s", mygroup); strcat(mytaskfile, "/tasks"); strcat(mysharesfile, "/cpu.shares"); pid = getpid(); write_to_file(mytaskfile, "a", pid); /* Assign task to it's group */ write_to_file(mysharesfile, "w", myshares); dbg("Default task's initial shares = %u", myshares); fd = SAFE_OPEN(cleanup, "./myfifo", 0); read(fd, &ch, 1); /* To fire all the tasks up at the same time */ /* * We need not calculate the expected % cpu time of this task, as * neither it is required nor it can be predicted as there are idle * system tasks (and others too) in this group. */ FLAG = 0; total_shares = 0; shares_pointer = &total_shares; len = strlen(path); if (!strncpy(fullpath, path, len)) tst_brkm(TBROK, cleanup, "Could not copy directory path %s ", path); if (scan_shares_files(shares_pointer) != 0) tst_brkm(TBROK, cleanup, "From function scan_shares_files in %s ", fullpath); /* return val -1 in case of function error, else 2 is min share value */ if ((fmyshares = read_shares_file(mysharesfile)) < 2) tst_brkm(TBROK, cleanup, "in reading shares files %s ", mysharesfile); if ((read_file(mytaskfile, GET_TASKS, &num_tasks)) < 0) tst_brkm(TBROK, cleanup, "in reading tasks files %s ", mytaskfile); exp_cpu_time = (double)(fmyshares * 100) / (total_shares * num_tasks); prev_time = time(NULL); /* Note down the time */ while (1) { /* * Need to run some cpu intensive task, which also * frequently checks the timer value */ double f = 274.345, mytime; /*just a float number for sqrt */ alarm(TIME_INTERVAL); timer_expired = 0; /* * Let the task run on cpu for TIME_INTERVAL. Time of this * operation should not be high otherwise we can exceed the * TIME_INTERVAL to measure cpu usage */ while (!timer_expired) f = sqrt(f * f); current_time = time(NULL); /* Duration in case its not exact TIME_INTERVAL */ delta_time = current_time - prev_time; getrusage(0, &cpu_usage); /* total_cpu_time = total user time + total sys time */ total_cpu_time = (cpu_usage.ru_utime.tv_sec + cpu_usage.ru_utime.tv_usec * 1e-6 + cpu_usage.ru_stime.tv_sec + cpu_usage.ru_stime.tv_usec * 1e-6); delta_cpu_time = total_cpu_time - prev_cpu_time; prev_cpu_time = total_cpu_time; prev_time = current_time; /* calculate % cpu time each task gets */ if (delta_time > TIME_INTERVAL) mytime = (delta_cpu_time * 100) / (delta_time * num_cpus); else mytime = (delta_cpu_time * 100) / (TIME_INTERVAL * num_cpus); /* * Lets print the results. The exp cpu time calculated may not * be correct due to running system tasks at the moment */ fprintf(stdout, "DEF TASK:CPU TIME{calc:-%6.2f(s)" " i.e. %6.2f(%%) exp:-%6.2f(%%)} with %lu(shares)" " in %lu (s) INTERVAL\n", delta_cpu_time, mytime, exp_cpu_time, myshares, delta_time); first_counter++; /* Take n sets of readings for each shares value */ if (first_counter >= NUM_INTERVALS) { first_counter = 0; second_counter++; if (second_counter >= NUM_SETS) exit(0); /* This task is done */ /* Keep same ratio but change values */ if (test_num == 1) { myshares = MULTIPLIER * myshares; write_to_file(mysharesfile, "w", myshares); } /* No need to change shares for def task for test 3 */ } /* end if */ } /* end while */ } /* end main */
/** * Set up engine. * */ static ods_status engine_setup(engine_type* engine) { ods_status status = ODS_STATUS_OK; struct sigaction action; int result = 0; int sockets[2] = {0,0}; ods_log_debug("[%s] setup signer engine", engine_str); if (!engine || !engine->config) { return ODS_STATUS_ASSERT_ERR; } /* set edns */ edns_init(&engine->edns, EDNS_MAX_MESSAGE_LEN); /* create command handler (before chowning socket file) */ engine->cmdhandler = cmdhandler_create(engine->allocator, engine->config->clisock_filename); if (!engine->cmdhandler) { return ODS_STATUS_CMDHANDLER_ERR; } engine->dnshandler = dnshandler_create(engine->allocator, engine->config->interfaces); engine->xfrhandler = xfrhandler_create(engine->allocator); if (!engine->xfrhandler) { return ODS_STATUS_XFRHANDLER_ERR; } if (engine->dnshandler) { if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) == -1) { return ODS_STATUS_XFRHANDLER_ERR; } engine->xfrhandler->dnshandler.fd = sockets[0]; engine->dnshandler->xfrhandler.fd = sockets[1]; status = dnshandler_listen(engine->dnshandler); if (status != ODS_STATUS_OK) { ods_log_error("[%s] setup: unable to listen to sockets (%s)", engine_str, ods_status2str(status)); } } /* privdrop */ engine->uid = privuid(engine->config->username); engine->gid = privgid(engine->config->group); /* TODO: does piddir exists? */ /* remove the chown stuff: piddir? */ ods_chown(engine->config->pid_filename, engine->uid, engine->gid, 1); ods_chown(engine->config->clisock_filename, engine->uid, engine->gid, 0); ods_chown(engine->config->working_dir, engine->uid, engine->gid, 0); if (engine->config->log_filename && !engine->config->use_syslog) { ods_chown(engine->config->log_filename, engine->uid, engine->gid, 0); } if (engine->config->working_dir && chdir(engine->config->working_dir) != 0) { ods_log_error("[%s] setup: unable to chdir to %s (%s)", engine_str, engine->config->working_dir, strerror(errno)); return ODS_STATUS_CHDIR_ERR; } if (engine_privdrop(engine) != ODS_STATUS_OK) { return ODS_STATUS_PRIVDROP_ERR; } /* set up hsm */ /* LEAK */ result = lhsm_open(engine->config->repositories); if (result != HSM_OK) { fprintf(stderr, "Fail to open hsm\n"); return ODS_STATUS_HSM_ERR; } /* daemonize */ if (engine->daemonize) { switch ((engine->pid = fork())) { case -1: /* error */ ods_log_error("[%s] setup: unable to fork daemon (%s)", engine_str, strerror(errno)); return ODS_STATUS_FORK_ERR; case 0: /* child */ break; default: /* parent */ engine_cleanup(engine); engine = NULL; xmlCleanupParser(); xmlCleanupGlobals(); xmlCleanupThreads(); exit(0); } if (setsid() == -1) { hsm_close(); ods_log_error("[%s] setup: unable to setsid daemon (%s)", engine_str, strerror(errno)); return ODS_STATUS_SETSID_ERR; } } engine->pid = getpid(); /* write pidfile */ if (util_write_pidfile(engine->config->pid_filename, engine->pid) == -1) { hsm_close(); return ODS_STATUS_WRITE_PIDFILE_ERR; } /* setup done */ ods_log_verbose("[%s] running as pid %lu", engine_str, (unsigned long) engine->pid); /* catch signals */ signal_set_engine(engine); action.sa_handler = signal_handler; sigfillset(&action.sa_mask); action.sa_flags = 0; sigaction(SIGTERM, &action, NULL); sigaction(SIGHUP, &action, NULL); sigaction(SIGINT, &action, NULL); sigaction(SIGILL, &action, NULL); sigaction(SIGUSR1, &action, NULL); sigaction(SIGALRM, &action, NULL); sigaction(SIGCHLD, &action, NULL); action.sa_handler = SIG_IGN; sigaction(SIGPIPE, &action, NULL); /* create workers/drudgers */ engine_create_workers(engine); engine_create_drudgers(engine); /* start cmd/dns/xfr handlers */ engine_start_cmdhandler(engine); engine_start_dnshandler(engine); engine_start_xfrhandler(engine); tsig_handler_init(engine->allocator); return ODS_STATUS_OK; }
int main(void) { int ret; struct sigaction sa, save; if (signal(SIGBUS, handler_1) == SIG_ERR) { perror("Failed to register signal handler"); return PTS_UNRESOLVED; } /* As whether signal handler is restored to default when executed is implementation defined, we cannot check it was registered here. */ /* Set the new signal handler with sigaction*/ sa.sa_flags = 0; sa.sa_handler = handler_2; ret = sigemptyset(&sa.sa_mask); if (ret != 0) { perror("Failed to empty signal set"); return PTS_UNRESOLVED; } ret = sigaction(SIGBUS, &sa, &save); if (ret != 0) { perror("Failed to register signal handler"); return PTS_UNRESOLVED; } /* Check the signal handler has been set up */ ret = raise(SIGBUS); if (ret != 0) { perror("Failed to raise signal"); return PTS_UNRESOLVED; } if (called != 0) { fprintf(stderr, "Handler was not executed\n"); return PTS_FAIL; } /* Restore the first signal handler */ ret = sigaction(SIGBUS, &save, 0); if (ret != 0) { perror("Failed to restore signal handler"); return PTS_UNRESOLVED; } /* Check the signal handler has been set up */ ret = raise(SIGBUS); if (ret != 0) { perror("Failed to raise signal"); return PTS_UNRESOLVED; } if (called != 1) { fprintf(stderr, "Handler was not executed\n"); return PTS_FAIL; } printf("Test PASSED\n"); return PTS_PASS; }
static void segv_handler(int sig) { struct sigaction action; // Unset our handler for this signal. action.sa_handler = SIG_DFL; action.sa_flags = 0; sigaction(sig, &action, NULL); void* array[64]; size_t size; int fd = STDERR_FILENO; char* pause_env = getenv("RBX_PAUSE_ON_CRASH"); if(pause_env) { long timeout = strtol(pause_env, NULL, 10); if(timeout <= 0) { timeout = 60; } else { timeout *= 60; } std::cerr << "\n========== CRASH (" << getpid(); std::cerr << "), pausing for " << timeout << " seconds to attach debugger\n"; sleep(timeout); } // If there is a report_path setup.. if(report_path[0]) { fd = open(report_path, O_WRONLY | O_CREAT | O_TRUNC, 0666); // If we can't open this path, use stderr. if(fd == -1) fd = STDERR_FILENO; } // print out all the frames to stderr static const char header[] = "Rubinius Crash Report #rbxcrashreport\n\n" "Error: signal "; safe_write(fd, header, sizeof(header)); write_sig(fd, sig); safe_write(fd, "\n\n[[Backtrace]]\n"); // get void*'s for all entries on the stack size = backtrace(array, 64); backtrace_symbols_fd(array, size, fd); // Try to get the output to flush... safe_write(fd, "\n[[System Info]]\n"); safe_write(fd, "sysname: "); safe_write(fd, machine_info.sysname); safe_write(fd, "\n"); safe_write(fd, "nodename: "); safe_write(fd, machine_info.nodename); safe_write(fd, "\n"); safe_write(fd, "release: "); safe_write(fd, machine_info.release); safe_write(fd, "\n"); safe_write(fd, "version: "); safe_write(fd, machine_info.version); safe_write(fd, "\n"); safe_write(fd, "machine: "); safe_write(fd, machine_info.machine); safe_write(fd, "\n"); // If we didn't write to stderr, then close the file down and // write info to stderr about reporting the error. if(fd != STDERR_FILENO) { close(fd); safe_write(STDERR_FILENO, "\n---------------------------------------------\n"); safe_write(STDERR_FILENO, "CRASH: A fatal error has occurred.\n\nBacktrace:\n"); backtrace_symbols_fd(array, size, 2); safe_write(STDERR_FILENO, "\n\n"); safe_write(STDERR_FILENO, "Wrote full error report to: "); safe_write(STDERR_FILENO, report_path); safe_write(STDERR_FILENO, "\nRun 'rbx report' to submit this crash report!\n"); } raise(sig); }
int main(void) { sem_t *mysemp; char semname[28]; int pid, status; sprintf(semname, "/" FUNCTION "_" TEST "_%d", getpid()); mysemp = sem_open(semname, O_CREAT, 0, 1); if (mysemp == SEM_FAILED || mysemp == NULL) { perror(ERROR_PREFIX "sem_open"); return PTS_UNRESOLVED; } if (sem_wait(mysemp) == -1) { perror(ERROR_PREFIX "sem_wait"); return PTS_UNRESOLVED; } pid = fork(); if (pid == 0) { // child create the semaphore. struct sigaction act; act.sa_handler = handler; act.sa_flags = 0; if (sigemptyset(&act.sa_mask) == -1) { perror("Error calling sigemptyset\n"); return CHILDFAIL; } if (sigaction(SIGABRT, &act, 0) == -1) { perror("Error calling sigaction\n"); return CHILDFAIL; } sem_wait(mysemp); if (errno == EINTR) { printf("Test PASSED\n"); return (CHILDPASS); } puts("TEST FAILED: errno != EINTR"); return (CHILDFAIL); } else { // parent to send a signal to child int i; sleep(1); status = kill(pid, SIGABRT); // send signal to child if (wait(&i) == -1) { perror("Error waiting for child to exit\n"); return PTS_UNRESOLVED; } if (!WEXITSTATUS(i)) { return PTS_FAIL; } puts("TEST PASSED"); sem_unlink(semname); return PTS_PASS; } return PTS_UNRESOLVED; }
int main (void) { struct sigaction sig_struct; sig_struct.sa_handler = sig_handler; sig_struct.sa_flags = 0; sigemptyset(&sig_struct.sa_mask); if (sigaction(SIGINT, &sig_struct, NULL) == -1) { cout << "Problem with sigaction" << endl; exit(1); } //string inputstate; /* gpio4 = new GPIOClass("4"); gpio24 = new GPIOClass("24"); gpio22 = new GPIOClass("22"); gpio4->export_gpio(); gpio24->export_gpio(); gpio22->export_gpio(); cout << " GPIO pins exported" << endl; gpio24->setdir_gpio("in"); gpio4->setdir_gpio("out"); gpio22->setdir_gpio("out"); cout << " Set GPIO pin directions" << endl; // vector container stores threads //gpio22->setval_gpio("0"); std::vector<std::thread> workers; for (int i = 0; i < 2; i++) { auto t = std::thread(&task, i); workers.push_back(std::move(t)); } std::cout << "main thread\n"; std::for_each(workers.begin(), workers.end(), [](std::thread &t) { //assert(t.joinable()); //t.join(); t.detach(); }); */ //int fd; fd = open("/dev/io_dev", O_RDWR); if(!(fd > 0)) { cout << "Device open is failed!!!"<<endl; return 0; } char buf[4]; char wbuf[4]; wbuf[0] = 1; wbuf[1] = 17; write(fd, wbuf, sizeof(wbuf)); std::vector<std::thread> workers; for (int i = 0; i < 2; i++) { auto t = std::thread(&task, i); workers.push_back(std::move(t)); } std::cout << "main thread\n"; std::for_each(workers.begin(), workers.end(), [](std::thread &t) { //assert(t.joinable()); //t.join(); t.detach(); }); std::cout << "main thread while\n"; while(1) { usleep(1000000); /* if(wbuf[0] == 0) wbuf[0] = 1; else wbuf[0] = 0; wbuf[1] = 0; write(fd, wbuf, sizeof(wbuf)); */ //gpio24->getval_gpio(inputstate); read(fd, buf, sizeof(buf)); /* cout << "message 0 : " << buf[0] << endl; cout << "message 1 : " << buf[1] << endl; cout << "message 2 : " << buf[2] << endl; cout << "message 3 : " << buf[3] << endl; */ printf("message 0 : %x \n", buf[0]); printf("message 1 : %x \n", buf[1]); printf("message 2 : %x \n", buf[2]); printf("message 3 : %x \n", buf[3]); //if(inputstate == "0") if(buf[0] == 0xb2) { cout << "input pin state is Pressed .n Will check input pin state again in 20ms "<<endl; usleep(20000); cout << "Checking again ....." << endl; //gpio24->getval_gpio(inputstate); read(fd, buf, sizeof(buf)); //if(inputstate == "0") if(buf[0] == 0xb2) { cout << "input pin state is definitely Pressed. Turning LED ON" <<endl; //gpio4->setval_gpio("1"); wbuf[0] = 1; wbuf[1] = 17; write(fd, wbuf, sizeof(wbuf)); cout << " Waiting until pin is unpressed....." << endl; //while (inputstate == "0"){ while (buf[0] == 0xb2){ //gpio24->getval_gpio(inputstate); read(fd, buf, sizeof(buf)); }; cout << "pin is unpressed" << endl; } else cout << "input pin state is definitely UnPressed. That was just noise." <<endl; } //gpio4->setval_gpio("0"); wbuf[0] = 0; wbuf[1] = 17; write(fd, wbuf, sizeof(wbuf)); /* gpio24->getval_gpio(inputstate); cout << "Current input pin state is " << inputstate <<endl; if(inputstate == "0") { cout << "input pin state is Pressed .n Will check input pin state again in 20ms "<<endl; usleep(20000); cout << "Checking again ....." << endl; gpio24->getval_gpio(inputstate); if(inputstate == "0") { cout << "input pin state is definitely Pressed. Turning LED ON" <<endl; gpio4->setval_gpio("1"); cout << " Waiting until pin is unpressed....." << endl; while (inputstate == "0"){ gpio24->getval_gpio(inputstate); }; cout << "pin is unpressed" << endl; } else cout << "input pin state is definitely UnPressed. That was just noise." <<endl; } gpio4->setval_gpio("0"); */ if(ctrl_c_pressed) { /* std::for_each(workers.begin(), workers.end(), [](std::thread &t) { //assert(t.joinable()); //t.join(); if(t.joinable()) { cout << "t.joinable()....." << endl; t.join(); } }); cout << "Ctrl^C Pressed" << endl; cout << "unexporting pins" << endl; gpio4->unexport_gpio(); gpio24->unexport_gpio(); cout << "deallocating GPIO Objects" << endl; delete gpio4; gpio4 = 0; delete gpio24; gpio24 =0; delete gpio22; gpio22 = 0; */ close(fd); break; } } cout << "Exiting....." << endl; return 0; }
/* * Set the signal handler for the specified signal. The routine figures * out what it should be set to. */ void setsignal(int signo) { int action; sig_t sigact = SIG_DFL; struct sigaction sa; char *t; if ((t = trap[signo]) == NULL) action = S_DFL; else if (*t != '\0') action = S_CATCH; else action = S_IGN; if (action == S_DFL) { switch (signo) { case SIGINT: action = S_CATCH; break; case SIGQUIT: #ifdef DEBUG { extern int debug; if (debug) break; } #endif action = S_CATCH; break; case SIGTERM: if (rootshell && iflag) action = S_IGN; break; #if JOBS case SIGTSTP: case SIGTTOU: if (rootshell && mflag) action = S_IGN; break; #endif #ifndef NO_HISTORY case SIGWINCH: if (rootshell && iflag) action = S_CATCH; break; #endif } } t = &sigmode[signo]; if (*t == 0) { /* * current setting unknown */ if (!getsigaction(signo, &sigact)) { /* * Pretend it worked; maybe we should give a warning * here, but other shells don't. We don't alter * sigmode, so that we retry every time. */ return; } if (sigact == SIG_IGN) { if (mflag && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)) { *t = S_IGN; /* don't hard ignore these */ } else *t = S_HARD_IGN; } else { *t = S_RESET; /* force to be set */ } } if (*t == S_HARD_IGN || *t == action) return; switch (action) { case S_DFL: sigact = SIG_DFL; break; case S_CATCH: sigact = onsig; break; case S_IGN: sigact = SIG_IGN; break; } *t = action; sa.sa_handler = sigact; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(signo, &sa, NULL); }
/** * Main function, starts the daemon. */ int main(int argc, char *argv[]) { struct sigaction action; int group, status = SS_RC_INITIALIZATION_FAILED; struct utsname utsname; /* logging for library during initialization, as we have no bus yet */ dbg = dbg_stderr; /* initialize library */ if (!library_init(NULL, "charon")) { library_deinit(); exit(SS_RC_LIBSTRONGSWAN_INTEGRITY); } if (lib->integrity && !lib->integrity->check_file(lib->integrity, "charon", argv[0])) { dbg_stderr(DBG_DMN, 1, "integrity check of charon failed"); library_deinit(); exit(SS_RC_DAEMON_INTEGRITY); } if (!libhydra_init()) { dbg_stderr(DBG_DMN, 1, "initialization failed - aborting charon"); libhydra_deinit(); library_deinit(); exit(SS_RC_INITIALIZATION_FAILED); } if (!libcharon_init()) { dbg_stderr(DBG_DMN, 1, "initialization failed - aborting charon"); goto deinit; } /* use CTRL loglevel for default */ for (group = 0; group < DBG_MAX; group++) { levels[group] = LEVEL_CTRL; } /* handle arguments */ for (;;) { struct option long_opts[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "use-syslog", no_argument, NULL, 'l' }, /* TODO: handle "debug-all" */ { "debug-dmn", required_argument, &group, DBG_DMN }, { "debug-mgr", required_argument, &group, DBG_MGR }, { "debug-ike", required_argument, &group, DBG_IKE }, { "debug-chd", required_argument, &group, DBG_CHD }, { "debug-job", required_argument, &group, DBG_JOB }, { "debug-cfg", required_argument, &group, DBG_CFG }, { "debug-knl", required_argument, &group, DBG_KNL }, { "debug-net", required_argument, &group, DBG_NET }, { "debug-asn", required_argument, &group, DBG_ASN }, { "debug-enc", required_argument, &group, DBG_ENC }, { "debug-tnc", required_argument, &group, DBG_TNC }, { "debug-imc", required_argument, &group, DBG_IMC }, { "debug-imv", required_argument, &group, DBG_IMV }, { "debug-pts", required_argument, &group, DBG_PTS }, { "debug-tls", required_argument, &group, DBG_TLS }, { "debug-esp", required_argument, &group, DBG_ESP }, { "debug-lib", required_argument, &group, DBG_LIB }, { 0,0,0,0 } }; int c = getopt_long(argc, argv, "", long_opts, NULL); switch (c) { case EOF: break; case 'h': usage(NULL); status = 0; goto deinit; case 'v': printf("Linux strongSwan %s\n", VERSION); status = 0; goto deinit; case 'l': use_syslog = TRUE; continue; case 0: /* option is in group */ levels[group] = atoi(optarg); continue; default: usage(""); status = 1; goto deinit; } break; } if (!lookup_uid_gid()) { dbg_stderr(DBG_DMN, 1, "invalid uid/gid - aborting charon"); goto deinit; } charon->load_loggers(charon, levels, !use_syslog); if (uname(&utsname) != 0) { memset(&utsname, 0, sizeof(utsname)); } DBG1(DBG_DMN, "Starting IKE charon daemon (strongSwan "VERSION", %s %s, %s)", utsname.sysname, utsname.release, utsname.machine); if (lib->integrity) { DBG1(DBG_DMN, "integrity tests enabled:"); DBG1(DBG_DMN, "lib 'libstrongswan': passed file and segment integrity tests"); DBG1(DBG_DMN, "lib 'libhydra': passed file and segment integrity tests"); DBG1(DBG_DMN, "lib 'libcharon': passed file and segment integrity tests"); DBG1(DBG_DMN, "daemon 'charon': passed file integrity test"); } /* initialize daemon */ if (!charon->initialize(charon, lib->settings->get_str(lib->settings, "charon.load", PLUGINS))) { DBG1(DBG_DMN, "initialization failed - aborting charon"); goto deinit; } lib->plugins->status(lib->plugins, LEVEL_CTRL); if (check_pidfile()) { DBG1(DBG_DMN, "charon already running (\""PID_FILE"\" exists)"); goto deinit; } if (!lib->caps->drop(lib->caps)) { DBG1(DBG_DMN, "capability dropping failed - aborting charon"); goto deinit; } /* add handler for SEGV and ILL, * INT, TERM and HUP are handled by sigwait() in run() */ action.sa_handler = segv_handler; action.sa_flags = 0; sigemptyset(&action.sa_mask); sigaddset(&action.sa_mask, SIGINT); sigaddset(&action.sa_mask, SIGTERM); sigaddset(&action.sa_mask, SIGHUP); sigaction(SIGSEGV, &action, NULL); sigaction(SIGILL, &action, NULL); sigaction(SIGBUS, &action, NULL); action.sa_handler = SIG_IGN; sigaction(SIGPIPE, &action, NULL); pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL); /* start daemon (i.e. the threads in the thread-pool) */ charon->start(charon); /* main thread goes to run loop */ run(); /* normal termination, cleanup and exit */ unlink_pidfile(); status = 0; deinit: libcharon_deinit(); libhydra_deinit(); library_deinit(); return status; }
int main(int argc, char **argv) { gid_t gid; addr_t addr; struct sigaction sa; int c, dFlag, vFlag; unsigned long max_message_size; const char *queuename, *tablename; ctxt = NULL; gid = (gid_t) -1; vFlag = dFlag = 0; tablename = queuename = NULL; if (NULL == (queue = queue_init())) { errx("queue_init failed"); // TODO: better } atexit(cleanup); sa.sa_handler = &on_signal; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sa.sa_flags = SA_RESTART; sigaction(SIGUSR1, &sa, NULL); if (NULL == (engine = get_default_engine())) { errx("no engine available for your system"); } while (-1 != (c = getopt_long(argc, argv, optstr, long_options, NULL))) { switch (c) { case 'b': { unsigned long val; if (parse_ulong(optarg, &val)) { queue_set_attribute(queue, QUEUE_ATTR_MAX_MESSAGE_SIZE, val); // TODO: check returned value } break; } case 'd': dFlag = 1; break; case 'e': { if (NULL == (engine = get_engine_by_name(optarg))) { errx("unknown engine '%s'", optarg); } break; } case 'g': { struct group *grp; if (NULL == (grp = getgrnam(optarg))) { errc("getgrnam failed"); } gid = grp->gr_gid; break; } case 'l': { logfilename = optarg; if (NULL == (err_file = fopen(logfilename, "a"))) { err_file = NULL; warnc("fopen '%s' failed, falling back to stderr", logfilename); } break; } case 'p': pidfilename = optarg; break; case 'q': queuename = optarg; break; case 's': { unsigned long val; if (parse_ulong(optarg, &val)) { queue_set_attribute(queue, QUEUE_ATTR_MAX_MESSAGE_IN_QUEUE, val); // TODO: check returned value } break; } case 't': tablename = optarg; break; case 'v': vFlag++; break; case 'h': default: usage(); } } argc -= optind; argv += optind; if (0 != argc || NULL == queuename || NULL == tablename) { usage(); } if (dFlag) { if (0 != daemon(0, !vFlag)) { errc("daemon failed"); } } if (NULL != pidfilename) { FILE *fp; if (NULL == (fp = fopen(pidfilename, "w"))) { warnc("can't create pid file '%s'", pidfilename); } else { fprintf(fp, "%ld\n", (long) getpid()); fclose(fp); } } if (((gid_t) -1) != gid) { if (0 != setgid(gid)) { errc("setgid failed"); } if (0 != setgroups(1, &gid)) { errc("setgroups failed"); } } CAP_RIGHTS_LIMIT(STDOUT_FILENO, CAP_WRITE); CAP_RIGHTS_LIMIT(STDERR_FILENO, CAP_WRITE); if (NULL != err_file/* && fileno(err_file) > 2*/) { CAP_RIGHTS_LIMIT(fileno(err_file), CAP_WRITE); } if (QUEUE_ERR_OK != queue_open(queue, queuename, QUEUE_FL_OWNER)) { errx("queue_open failed"); // TODO: better } if (QUEUE_ERR_OK != queue_get_attribute(queue, QUEUE_ATTR_MAX_MESSAGE_SIZE, &max_message_size)) { errx("queue_get_attribute failed"); // TODO: better } if (NULL == (buffer = calloc(++max_message_size, sizeof(*buffer)))) { errx("calloc failed"); } if (NULL != engine->open) { ctxt = engine->open(tablename); } if (0 == getuid() && engine->drop_privileges) { struct passwd *pwd; if (NULL == (pwd = getpwnam("nobody"))) { if (NULL == (pwd = getpwnam("daemon"))) { errx("no nobody or daemon user accounts found on this system"); } } if (0 != setuid(pwd->pw_uid)) { errc("setuid failed"); } } CAP_ENTER(); while (1) { ssize_t read; if (-1 == (read = queue_receive(queue, buffer, max_message_size))) { errc("queue_receive failed"); // TODO: better } else { if (!parse_addr(buffer, &addr)) { errx("parsing of '%s' failed", buffer); // TODO: better } else { engine->handle(ctxt, tablename, addr); } } } /* not reached */ return BANIPD_EXIT_SUCCESS; }
gboolean install_package(std::string package_file, std::string destination) { char *tar_cmd = NULL; std::ostringstream command; // Find the absolute path to the 'tar' command. tar_cmd = g_find_program_in_path("tar"); if (!tar_cmd) { llerrs << "`tar' was not found in $PATH" << llendl; return FALSE; } llinfos << "Found tar command: " << tar_cmd << llendl; // Unpack the tarball in a temporary place first, then move it to // its final destination std::string tmp_dest_dir = gDirUtilp->getTempFilename(); if (LLFile::mkdir(tmp_dest_dir, 0744)) { llerrs << "Failed to create directory: " << destination << llendl; return FALSE; } char *package_file_string_copy = g_strdup(package_file.c_str()); char *tmp_dest_dir_string_copy = g_strdup(tmp_dest_dir.c_str()); gchar *argv[8] = { tar_cmd, const_cast<gchar*>("--strip"), const_cast<gchar*>("1"), const_cast<gchar*>("-xjf"), package_file_string_copy, const_cast<gchar*>("-C"), tmp_dest_dir_string_copy, NULL, }; llinfos << "Untarring package: " << package_file << llendl; // store current SIGCHLD handler if there is one, replace with default // handler to make glib happy struct sigaction sigchld_backup; struct sigaction sigchld_appease_glib; sigchld_appease_glib.sa_handler = SIG_DFL; sigemptyset(&sigchld_appease_glib.sa_mask); sigchld_appease_glib.sa_flags = 0; sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup); gchar *stderr_output = NULL; gint child_exit_status = 0; GError *untar_error = NULL; if (!less_anal_gspawnsync(argv, &stderr_output, &child_exit_status, &untar_error)) { llwarns << "Failed to spawn child process: " << untar_error->message << llendl; return FALSE; } if (child_exit_status) { llwarns << "Untar command failed: " << (stderr_output ? stderr_output : "(no reason given)") << llendl; return FALSE; } g_free(tar_cmd); g_free(package_file_string_copy); g_free(tmp_dest_dir_string_copy); g_free(stderr_output); if (untar_error) g_error_free(untar_error); // move the existing package out of the way if it exists if (gDirUtilp->fileExists(destination)) { std::string backup_dir = destination + ".backup"; int oldcounter = 1; while (gDirUtilp->fileExists(backup_dir)) { // find a foo.backup.N folder name that isn't taken yet backup_dir = destination + ".backup." + llformat("%d", oldcounter); ++oldcounter; } if (rename_with_sudo_fallback(destination, backup_dir)) { llwarns << "Failed to move directory: '" << destination << "' -> '" << backup_dir << llendl; return FALSE; } } // The package has been unpacked in a staging directory, now we just // need to move it to its destination. if (rename_with_sudo_fallback(tmp_dest_dir, destination)) { llwarns << "Failed to move installation to the destination: " << destination << llendl; return FALSE; } // \0/ Success! return TRUE; }
int main(int argc, char **argv) { int i, j; char *name; struct sockaddr_un sa; struct sigaction scurrent, srestore; int fd, run, ring, result, answer, have, flags; unsigned int count; struct termios termattr, termrestore; char input, format; fd_set fsr; char remote[BUFFER], local[SMALL]; IDSA_EVENT *event; IDSA_PRINT_HANDLE *handle; char *bright, *normal; ring = 0; name = NULL; handle = NULL; answer = 0; result = EX_OK; i = j = 1; while (i < argc) { if (argv[i][0] == '-') { switch (argv[i][j]) { case 'c': printf("(c) 2002 Marc Welz: Licensed under the GNU GPL\n"); return EX_OK; case 'h': usage(argv[0]); return EX_OK; case 'b': ring = 1; break; case 'F': case 'f': format = argv[i][j]; j++; if (argv[i][j] == '\0') { j = 0; i++; } if (i < argc) { handle = (format == 'f') ? idsa_print_format(argv[i] + j) : idsa_print_parse(argv[i] + j); if (handle == NULL) { fprintf(stderr, "%s: unable to process output format %s\n", argv[0], argv[i] + j); return EX_SOFTWARE; } i++; j = 0; } else { fprintf(stderr, "%s: -%c option requires an output format as parameter\n", argv[0], format); return EX_USAGE; } break; case '-': break; case '\0': j = 0; i++; break; default: fprintf(stderr, "%s: Unknown option -%c\n", argv[0], argv[i][j]); return EX_USAGE; break; } j++; } else { name = argv[i]; i++; } } if (name == NULL) { fprintf(stderr, "%s: Need a unix domain socket\n", argv[0]); return EX_USAGE; } if (handle == NULL) { handle = idsa_print_format("internal"); if (handle == NULL) { fprintf(stderr, "%s: Internal failure, unable to process default print format\n", argv[0]); return EX_SOFTWARE; } } if (!isatty(STDIN_FILENO)) { fprintf(stderr, "%s: My standard input needs to be an interactive terminal\n", argv[0]); return EX_USAGE; } event = idsa_event_new(0); if (event == NULL) { fprintf(stderr, "%s: Unable to allocate data for an event\n", argv[0]); return EX_SOFTWARE; } bright = NULL; normal = NULL; #ifdef STANDOUT if (setupterm(NULL, STDOUT_FILENO, &result) == OK) { bright = tigetstr("smso"); normal = tigetstr("rmso"); } #endif signal(SIGPIPE, SIG_IGN); sa.sun_family = AF_UNIX; strncpy(sa.sun_path, name, sizeof(sa.sun_path)); fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { fprintf(stderr, "%s: Unable to create socket: %s\n", argv[0], strerror(errno)); return EX_OSERR; } printf("Connecting to %s ... ", name); fflush(stdout); sigfillset(&(scurrent.sa_mask)); scurrent.sa_flags = 0; scurrent.sa_handler = fail; sigaction(SIGALRM, &scurrent, &srestore); alarm(TIMEOUT); if (connect(fd, (struct sockaddr *) &sa, sizeof(sa))) { printf("failed\n"); fprintf(stderr, "%s: Connect failed: %s\n", argv[0], strerror(errno)); return EX_OSERR; } printf("ok\n"); flags = fcntl(fd, F_GETFL, 0); if ((flags == (-1)) || (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == (-1))) { fprintf(stderr, "%s: Unable to make socket %s nonblocking: %s\n", argv[0], name, strerror(errno)); return EX_OSERR; } alarm(0); sigaction(SIGALRM, &srestore, NULL); count = 1; fflush(stdout); fflush(stderr); if (tcgetattr(STDIN_FILENO, &termrestore) || tcgetattr(STDIN_FILENO, &termattr)) { fprintf(stderr, "%s: Unable to get terminal information: %s\n", argv[0], strerror(errno)); return EX_OSERR; } termattr.c_lflag &= ~(ICANON | ECHO); termattr.c_cc[VMIN] = 0; termattr.c_cc[VTIME] = 0; if (tcsetattr(STDIN_FILENO, TCSANOW, &termattr)) { fprintf(stderr, "%s: Unable to change terminal properties: %s\n", argv[0], strerror(errno)); return EX_OSERR; } printf("%s version %s: Press ? for help\n", argv[0], VERSION); run = STATE_REQUEST; while (run != STATE_QUIT) { FD_ZERO(&fsr); FD_SET(fd, &fsr); FD_SET(STDIN_FILENO, &fsr); if (select(fd + 1, &fsr, NULL, NULL, NULL) <= 0) { fprintf(stderr, "%s: Select failed: %s\n", argv[0], strerror(errno)); run = STATE_QUIT; result = EX_OSERR; } if (FD_ISSET(fd, &fsr)) { #ifdef TRACE fprintf(stderr, "main(): socket active\n"); #endif have = 0; do { result = read(fd, remote + have, BUFFER - have); if (result <= 0) { if (result == 0) { fprintf(stderr, "%s: Remote side on socket %s closed connection\n", argv[0], name); run = STATE_QUIT; result = EX_SOFTWARE; } else { switch (errno) { case EAGAIN: case EINTR: result = have; break; default: fprintf(stderr, "%s: Read from socket %s failed: %s\n", argv[0], name, strerror(errno)); run = STATE_QUIT; result = EX_OSERR; break; } } } else { have += result; } if (result > 0) { switch (run) { case STATE_REQUEST: #ifdef TRACE fprintf(stderr, "main(): converted %d to buffer with size %d\n", result, have); #endif result = idsa_event_frombuffer(event, remote, have); if (result <= 0) { fprintf(stderr, "%s: Read malformed event from socket %s\n", argv[0], name); run = STATE_QUIT; result = EX_SOFTWARE; } else { /* FIXME: could be a fancy print */ output(event, handle); if (result < have) { memmove(remote, remote + result, have - result); have -= result; } else { have = 0; } run = STATE_CLICK; } /* FIXME: what about lots of events in single read ? */ break; case STATE_CLICK: case STATE_REPLY: switch (remote[0]) { case 'A': case 'D': result = snprintf(local, SMALL, "%c%u\n", remote[0], count); #ifdef TRACE fprintf(stderr, "main(): comparing %d bytes of %s against buffer of %d %32s\n", result, local, have, remote); #endif if (strncmp(local, remote, result)) { fprintf(stderr, "%s: Received malformed answer from socket %s\n", argv[0], name); run = STATE_QUIT; result = EX_SOFTWARE; } else { #ifdef STANDOUT if (bright) putp(bright); #endif puts((remote[0] == 'A') ? "allowed" : "denied"); #ifdef STANDOUT if (normal) putp(normal); #endif if (result < have) { memmove(remote, remote + result, have - result); have -= result; } else { have = 0; } count++; run = STATE_REQUEST; } break; default: fprintf(stderr, "%s: Read malformed answer from socket %s\n", argv[0], name); run = STATE_QUIT; result = EX_SOFTWARE; break; } break; } } } while ((result > 0) && (run != STATE_QUIT)); if (ring && (run == STATE_CLICK)) { putchar('\a'); fflush(stdout); } } input = 0; if (FD_ISSET(STDIN_FILENO, &fsr)) { #ifdef TRACE fprintf(stderr, "main(): terminal active\n"); #endif do { result = read(STDIN_FILENO, local, SMALL); switch (result) { case -1: switch (errno) { case EAGAIN: case EINTR: break; default: fprintf(stderr, "%s: Read from terminal failed: %s\n", argv[0], strerror(errno)); run = STATE_QUIT; result = EX_OSERR; break; } break; case 0: break; default: input = local[result - 1]; break; } } while ((result > 0) && (run != STATE_QUIT)); } #ifdef TRACE fprintf(stderr, "main(): input is 0x%02x, state=%d\n", input, run); #endif switch (input) { case 'q': case 'x': run = STATE_QUIT; result = EX_OK; input = 0; break; case 'h': case '?': help(argv[0]); input = 0; break; case 'a': case 'A': answer = 1; break; case 'd': case 'D': answer = 0; break; case 's': ring = 0; printf("bell disabled\n"); break; case 'b': ring = 1; printf("bell activated\a\n"); break; } if ((input > 0) && (run == STATE_CLICK)) { result = snprintf(local, SMALL - 1, "%c%u\n", (answer ? 'A' : 'D'), count); #ifdef TRACE fprintf(stderr, "main(): writing: %s", local); #endif if (result != write(fd, local, result)) { fprintf(stderr, "%s: write to socket %s failed: %s\n", argv[0], name, strerror(errno)); run = STATE_QUIT; result = EX_OSERR; } else { run = STATE_REPLY; } } } if (tcsetattr(STDIN_FILENO, TCSANOW, &termrestore)) { fprintf(stderr, "%s: Unable to restore terminal properties: %s\n", argv[0], strerror(errno)); return EX_OSERR; } return result; }
static int exec_conf(void) { int pipefd[2], stat, size; struct sigaction sa; sigset_t sset, osset; sigemptyset(&sset); sigaddset(&sset, SIGINT); sigprocmask(SIG_BLOCK, &sset, &osset); signal(SIGINT, SIG_DFL); sa.sa_handler = winch_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGWINCH, &sa, NULL); *argptr++ = NULL; pipe(pipefd); pid = fork(); if (pid == 0) { sigprocmask(SIG_SETMASK, &osset, NULL); dup2(pipefd[1], 2); close(pipefd[0]); close(pipefd[1]); execv(args[0], args); _exit(EXIT_FAILURE); } close(pipefd[1]); bufptr = input_buf; while (1) { size = input_buf + sizeof(input_buf) - bufptr; size = read(pipefd[0], bufptr, size); if (size <= 0) { if (size < 0) { if (errno == EINTR || errno == EAGAIN) continue; perror("read"); } break; } bufptr += size; } *bufptr++ = 0; close(pipefd[0]); waitpid(pid, &stat, 0); if (do_resize) { init_wsize(); do_resize = 0; sigprocmask(SIG_SETMASK, &osset, NULL); return -1; } if (WIFSIGNALED(stat)) { printf("\finterrupted(%d)\n", WTERMSIG(stat)); exit(1); } #if 0 printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf); sleep(1); #endif sigpending(&sset); if (sigismember(&sset, SIGINT)) { printf("\finterrupted\n"); exit(1); } sigprocmask(SIG_SETMASK, &osset, NULL); return WEXITSTATUS(stat); }
int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) { unsigned char buf[16]; struct sigaction sa; struct pollfd p; sigset_t sigs; char addr[18]; int i, fd, sk, len; struct celluon_state s; sk = rfcomm_connect(src, dst, channel); if (sk < 0) return -1; fd = uinput_create("Celluon Keyboard", 1, 0); if (fd < 0) { close(sk); return -1; } ba2str(dst, addr); printf("Connected to %s on channel %d\n", addr, channel); printf("Press CTRL-C for hangup\n"); memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sa.sa_handler = sig_term; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sa.sa_handler = sig_hup; sigaction(SIGHUP, &sa, NULL); sigfillset(&sigs); sigdelset(&sigs, SIGCHLD); sigdelset(&sigs, SIGPIPE); sigdelset(&sigs, SIGTERM); sigdelset(&sigs, SIGINT); sigdelset(&sigs, SIGHUP); p.fd = sk; p.events = POLLIN | POLLERR | POLLHUP; memset(&s, 0, sizeof(s)); while (!__io_canceled) { p.revents = 0; if (ppoll(&p, 1, NULL, &sigs) < 1) continue; len = read(sk, buf, sizeof(buf)); if (len < 0) break; for (i = 0; i < len; i++) celluon_decode(fd, &s, buf[i]); } printf("Disconnected\n"); ioctl(fd, UI_DEV_DESTROY); close(fd); close(sk); return 0; }