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