xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

lnx_kmod.c (2998B)


      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  */
     36 int
     37 xf86LoadKernelModule(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 }