int main(int argc, char **argv) { int c, i, retval; int option = LOG_NDELAY; pid_t pid, sid; size_t argv0_len, procname_len, max_procname_len; progname = argv[0]; shm_common_init(); while (1) { int option_index = 0; int curind = optind; c = getopt_long (argc, argv, "hI:sFf:i:S", long_options, &option_index); if (c == -1) break; switch (c) { case 'F': foreground++; break; case 'I': rtapi_instance = atoi(optarg); break; case 'R': hal_thread_stack_size = atoi(optarg); break; case 'i': instance_name = optarg; break; case 'f': if ((flavor = flavor_byname(optarg)) == NULL) { fprintf(stderr, "no such flavor: '%s' -- valid flavors are:\n", optarg); flavor_ptr f = flavors; while (f->name) { fprintf(stderr, "\t%s\n", f->name); f++; } exit(1); } break; case 'u': usr_msglevel = atoi(optarg); break; case 'r': rt_msglevel = atoi(optarg); break; case 'H': halsize = atoi(optarg); break; case 'S': use_shmdrv++; break; case 's': log_stderr++; option |= LOG_PERROR; break; case '?': if (optopt) fprintf(stderr, "bad short opt '%c'\n", optopt); else fprintf(stderr, "bad long opt \"%s\"\n", argv[curind]); exit(1); break; default: usage(argc, argv); exit(0); } } // sanity if (getuid() == 0) { fprintf(stderr, "%s: FATAL - will not run as root\n", progname); exit(EXIT_FAILURE); } if (geteuid() == 0) { fprintf(stderr, "%s: FATAL - will not run as setuid root\n", progname); exit(EXIT_FAILURE); } if (flavor == NULL) flavor = default_flavor(); if (flavor == NULL) { fprintf(stderr, "%s: FATAL - failed to detect thread flavor\n", progname); exit(EXIT_FAILURE); } // can we actually run what's being suggested? if (!flavor_and_kernel_compatible(flavor)) { fprintf(stderr, "%s: FATAL - cant run the %s flavor on this kernel\n", progname, flavor->name); exit(EXIT_FAILURE); } // catch installation error: user not in xenomai group if (flavor->id == RTAPI_XENOMAI_ID) { int retval = user_in_xenomai_group(); switch (retval) { case 1: // yes break; case 0: fprintf(stderr, "this user is not member of group xenomai\n"); fprintf(stderr, "please 'sudo adduser <username> xenomai'," " logout and login again\n"); exit(EXIT_FAILURE); default: fprintf(stderr, "cannot determine if this user " "is a member of group xenomai: %s\n", strerror(-retval)); exit(EXIT_FAILURE); } } // do we need the shmdrv module? if (((flavor->flags & FLAVOR_KERNEL_BUILD) || use_shmdrv) && !shmdrv_available()) { fprintf(stderr, "%s: FATAL - %s requires the shmdrv module loaded\n", progname, use_shmdrv ? "--shmdrv" : flavor->name); exit(EXIT_FAILURE); } // the global segment every entity in HAL/RTAPI land attaches to if ((retval = create_global_segment()) != 1) // must be a new shm segment exit(retval); // good to go if (!foreground) { pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0); sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); } #if 0 if ((chdir("/")) < 0) { exit(EXIT_FAILURE); } #endif } snprintf(proctitle, sizeof(proctitle), "msgd:%d",rtapi_instance); openlog_async(proctitle, option , SYSLOG_FACILITY); // set new process name argv0_len = strlen(argv[0]); procname_len = strlen(proctitle); max_procname_len = (argv0_len > procname_len) ? (procname_len) : (argv0_len); strncpy(argv[0], proctitle, max_procname_len); memset(&argv[0][max_procname_len], '\0', argv0_len - max_procname_len); for (i = 1; i < argc; i++) memset(argv[i], '\0', strlen(argv[i])); // this is the single place in all of linuxCNC where the global segment // gets initialized - no reinitialization from elsewhere init_global_data(global_data, flavor->id, rtapi_instance, halsize, rt_msglevel, usr_msglevel, instance_name,hal_thread_stack_size); syslog_async(LOG_INFO, "startup instance=%s pid=%d flavor=%s " "rtlevel=%d usrlevel=%d halsize=%d shm=%s gcc=%s version=%s", global_data->instance_name, getpid(), flavor->name, global_data->rt_msg_level, global_data->user_msg_level, global_data->hal_size, shmdrv_loaded ? "shmdrv" : "Posix", __VERSION__, GIT_VERSION); syslog_async(LOG_INFO,"configured: %s sha=%s", CONFIG_DATE, GIT_CONFIG_SHA); syslog_async(LOG_INFO,"built: %s %s sha=%s", __DATE__, __TIME__, GIT_BUILD_SHA); if (strcmp(GIT_CONFIG_SHA,GIT_BUILD_SHA)) syslog_async(LOG_WARNING, "WARNING: git SHA's for configure and build do not match!"); if ((global_data->rtapi_msgd_pid != 0) && kill(global_data->rtapi_msgd_pid, 0) == 0) { fprintf(stderr,"%s: another rtapi_msgd is already running (pid %d), exiting\n", progname, global_data->rtapi_msgd_pid); exit(EXIT_FAILURE); } else { global_data->rtapi_msgd_pid = getpid(); } close(STDIN_FILENO); close(STDOUT_FILENO); if (!log_stderr) close(STDERR_FILENO); message_thread(); // signal received - check if rtapi_app running, and shut it down cleanup_actions(); closelog_async(); exit(exit_code); }
int shm_common_init(void) { page_size = sysconf(_SC_PAGESIZE); shmdrv_loaded = shmdrv_available(); return 0; }