summaryrefslogtreecommitdiffstats
path: root/qemu/tests/tcg/cris/check_glibc_kernelversion.c
blob: 07448722c001357e90c19219608545cf2601dfe1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
 * Check the lz insn.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "sys.h"

#define __LINUX_KERNEL_VERSION 131584

#define DL_SYSDEP_OSCHECK(FATAL) \
  do {                                                                        \
    /* Test whether the kernel is new enough.  This test is only              \
       performed if the library is not compiled to run on all                 \
       kernels.  */                                                           \
    if (__LINUX_KERNEL_VERSION > 0)                                           \
      {                                                                       \
        char bufmem[64];                                                      \
        char *buf = bufmem;                                                   \
        unsigned int version;                                                 \
        int parts;                                                            \
        char *cp;                                                             \
        struct utsname uts;                                                   \
                                                                              \
        /* Try the uname syscall */                                           \
        if (__uname (&uts))                                                   \
          {                                                                   \
            /* This was not successful.  Now try reading the /proc            \
               filesystem.  */                                                \
            ssize_t reslen;                                                   \
            int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY);         \
            if (fd == -1                                                      \
                || (reslen = __read (fd, bufmem, sizeof (bufmem))) <= 0)      \
              /* This also didn't work.  We give up since we cannot           \
                 make sure the library can actually work.  */                 \
              FATAL ("FATAL: cannot determine library version\n");            \
            __close (fd);                                                     \
            buf[MIN (reslen, (ssize_t) sizeof (bufmem) - 1)] = '\0';          \
          }                                                                   \
        else                                                                  \
          buf = uts.release;                                                  \
                                                                              \
        /* Now convert it into a number.  The string consists of at most      \
           three parts.  */                                                   \
        version = 0;                                                          \
        parts = 0;                                                            \
        cp = buf;                                                             \
        while ((*cp >= '0') && (*cp <= '9'))                                  \
          {                                                                   \
            unsigned int here = *cp++ - '0';                                  \
                                                                              \
            while ((*cp >= '0') && (*cp <= '9'))                              \
              {                                                               \
                here *= 10;                                                   \
                here += *cp++ - '0';                                          \
              }                                                               \
                                                                              \
            ++parts;                                                          \
            version <<= 8;                                                    \
            version |= here;                                                  \
                                                                              \
            if (*cp++ != '.')                                                 \
              /* Another part following?  */                                  \
              break;                                                          \
          }                                                                   \
                                                                              \
        if (parts < 3)                                                        \
          version <<= 8 * (3 - parts);                                        \
                                                                              \
        /* Now we can test with the required version.  */                     \
        if (version < __LINUX_KERNEL_VERSION)                                 \
          /* Not sufficient.  */                                               \
          FATAL ("FATAL: kernel too old\n");                                  \
                                                                              \
        _dl_osversion = version;                                              \
      }                                                                       \
  } while (0)

int main(void)
{
        char bufmem[64] = "2.6.22";
        char *buf = bufmem;
        unsigned int version;
        int parts;
        char *cp;

        version = 0;
        parts = 0;
        cp = buf;
        while ((*cp >= '0') && (*cp <= '9'))
          {
            unsigned int here = *cp++ - '0';

            while ((*cp >= '0') && (*cp <= '9'))
              {
                here *= 10;
                here += *cp++ - '0';
              }

            ++parts;
            version <<= 8;
            version |= here;

            if (*cp++ != '.')
              /* Another part following?  */
              break;
          }

        if (parts < 3)
          version <<= 8 * (3 - parts);
	if (version < __LINUX_KERNEL_VERSION)
		err();
	pass();
	exit(0);
}