static char *loadrt_generator(const char *text, int state) { static int len; static DIR *d; struct dirent *ent; char rtlibdir[PATH_MAX]; if (get_rtapi_config(rtlibdir,"RTLIB_DIR",PATH_MAX) != 0) return NULL; strcat(rtlibdir,"/"); strcat(rtlibdir, current_flavor->name); strcat(rtlibdir,"/"); if(!state) { len = strlen(text); d = opendir(rtlibdir); } while(d && (ent = readdir(d))) { char *result; if(!strstr(ent->d_name, default_flavor()->mod_ext)) continue; if(startswith(ent->d_name, "rtapi.")) continue; if(startswith(ent->d_name, "hal_lib.")) continue; if(strncmp(text, ent->d_name, len) != 0) continue; result = strdup(ent->d_name); result[strlen(result) - \ strlen(default_flavor()->mod_ext)] = 0; return result; } if (d != NULL) { closedir(d); } return NULL; }
int module_path(char *result, const char *basename) { /* Find a kernel module's path */ struct stat sb; char buf[PATH_MAX]; char rtlib_result[PATH_MAX]; int has_rtdir; struct utsname uts; // Initialize kmodule_dir, only once if (kmodule_dir[0] == 0) { uname(&uts); get_rtapi_config(buf,"RUN_IN_PLACE",4); if (strncmp(buf,"yes",3) == 0) { // Complete RTLIB_DIR should be <RTLIB_DIR>/<flavor>/<uname -r> if (get_rtapi_config(buf,"RTLIB_DIR",PATH_MAX) != 0) return -ENOENT; if (strcmp(default_flavor()->build_sys,"user-dso") == 0) { // point user threads to a common directory snprintf(kmodule_dir,PATH_MAX,"%s/userland/%s", buf, uts.release); } else { // kthreads each have their own directory snprintf(kmodule_dir,PATH_MAX,"%s/%s/%s", buf, default_flavor()->name, uts.release); } } else { // Complete RTLIB_DIR should be /lib/modules/<uname -r>/linuxcnc snprintf(kmodule_dir, PATH_MAX, "/lib/modules/%s/linuxcnc", uts.release); } } // Look for module in kmodule_dir/RTLIB_DIR snprintf(result, PATH_MAX, "%s/%s.ko", kmodule_dir, basename); if ((stat(result, &sb) == 0) && (S_ISREG(sb.st_mode))) return 0; // Not found; save result for possible later diagnostic msg strcpy(rtlib_result,result); // Check RTDIR as well (RTAI) has_rtdir = (get_rtapi_config(buf, "RTDIR", PATH_MAX) == 0 && buf[0] != 0); if (has_rtdir) { snprintf(result, PATH_MAX, "%s/%s.ko", buf, basename); if ((stat(result, &sb) == 0) && (S_ISREG(sb.st_mode))) return 0; } // Module not found fprintf(stderr, "module '%s.ko' not found in directory\n\t%s\n", basename, kmodule_dir); if (has_rtdir) fprintf(stderr, "\tor directory %s\n", buf); return -ENOENT; }
int get_rtapi_config(char *result, const char *param, int n) { /* Read a parameter value from rtapi.ini. First try the flavor section, then the global section. Copy max n-1 bytes into result buffer. */ char *val; val = get_rtapi_param(default_flavor()->name, param); // Return if nothing found if (val==NULL) { result[0] = 0; return -1; } // Otherwise copy result into buffer (see 'WTF' comment in inifile.cc) strncpy(result, val, n-1); return 0; }
int rtapi_get_tags(const char *mod_name) { char modpath[PATH_MAX]; int result = 0, n = 0; char *cp1 = ""; flavor_ptr flavor = default_flavor(); if (kernel_threads(flavor)) { if (module_path(modpath, mod_name) < 0) { perror("module_path"); return -1; } } else { if (get_rtapi_config(modpath,"RTLIB_DIR",PATH_MAX) != 0) { perror("cant get RTLIB_DIR ?\n"); return -1; } strcat(modpath,"/"); strcat(modpath, flavor->name); strcat(modpath,"/"); strcat(modpath,mod_name); strcat(modpath, flavor->mod_ext); } const char **caps = get_caps(modpath); char **p = (char **)caps; while (p && *p && strlen(*p)) { cp1 = *p++; if (strncmp(cp1,"HAL=", 4) == 0) { n = strtol(&cp1[4], NULL, 10); result |= n ; } } free(caps); return result; }
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); }