Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
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;
}
Example #5
0
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);
}