1 2#ifdef HAVE_XORG_CONFIG_H 3#include <xorg-config.h> 4#endif 5 6#include <errno.h> 7#include <fcntl.h> 8#include <unistd.h> 9#include <sys/wait.h> 10#include <signal.h> 11#include "xf86_OSlib.h" 12#include "xf86.h" 13 14 15#define MODPROBE_PATH_FILE "/proc/sys/kernel/modprobe" 16#define MAX_PATH 1024 17 18 19#if 0 20/* XFree86 #defines execl to be the xf86execl() function which does 21 * a fork AND exec. We don't want that. We want the regular, 22 * standard execl(). 23 */ 24#ifdef execl 25#undef execl 26#endif 27#endif 28 29 30/* 31 * Load a Linux kernel module. 32 * This is used by the DRI/DRM to load a DRM kernel module when 33 * the X server starts. It could be used for other purposes in the future. 34 * Input: 35 * modName - name of the kernel module (Ex: "tdfx") 36 * Return: 37 * 0 for failure, 1 for success 38 */ 39int 40xf86LoadKernelModule(const char *modName) 41{ 42 char mpPath[MAX_PATH] = ""; 43 int fd = -1, status, n; 44 pid_t pid; 45 46 /* get the path to the modprobe program */ 47 fd = open(MODPROBE_PATH_FILE, O_RDONLY); 48 if (fd >= 0) { 49 int count = read(fd, mpPath, MAX_PATH - 1); 50 if (count <= 0) { 51 mpPath[0] = 0; 52 } 53 else if (mpPath[count - 1] == '\n') { 54 mpPath[count - 1] = 0; /* replaces \n with \0 */ 55 } 56 close(fd); 57 /* if this worked, mpPath will be "/sbin/modprobe" or similar. */ 58 } 59 60 if (mpPath[0] == 0) { 61 /* we failed to get the path from the system, use a default */ 62 strcpy(mpPath, "/sbin/modprobe"); 63 } 64 65 /* now fork/exec the modprobe command */ 66 /* 67 * It would be good to capture stdout/stderr so that it can be directed 68 * to the log file. modprobe errors currently are missing from the log 69 * file. 70 */ 71 switch (pid = fork()) { 72 case 0: /* child */ 73 /* change real/effective user ID to 0/0 as we need to 74 * preinstall agpgart module for some DRM modules 75 */ 76 if (setreuid(0,0)) { 77 xf86Msg(X_WARNING,"LoadKernelModule: " 78 "Setting of real/effective user Id to 0/0 failed"); 79 } 80 setenv("PATH","/sbin",1); 81 n = execl(mpPath, "modprobe", modName, NULL); 82 xf86Msg(X_WARNING,"LoadKernelModule %s\n",strerror(errno)); 83 exit(EXIT_FAILURE); /* if we get here the child's exec failed */ 84 break; 85 case -1: /* fork failed */ 86 return 0; 87 default: /* fork worked */ 88 { 89 /* XXX we loop over waitpid() because it sometimes fails on 90 * the first attempt. Don't know why! 91 */ 92 int count = 0, p; 93 do { 94 p = waitpid(pid, &status, 0); 95 } while (p == -1 && count++ < 4); 96 97 if (p == -1) { 98 return 0; 99 } 100 101 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 102 return 1; /* success! */ 103 } 104 else { 105 return 0; 106 } 107 } 108 } 109 110 /* never get here */ 111 return 0; 112} 113