/* Simple test to check that device nodes are correctly created and visible */ #include #include #include #include #include #include #include #include #define TEST_MINOR 120 #define TEST_MAJOR 25 void usage(char *prog) { fprintf(stderr, "usage: %s \n", prog); exit(1); } /* * this stuff inlined here instead of using appropriate header * to avoid linking to symbols which is not present in newer libc. * Currently this is the case, as UML image contains RedHat 9 and * developers use something newer (Fedora, etc.) --umka */ inline unsigned int __gnu_dev_major (unsigned long long int __dev) { return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff); } inline unsigned int __gnu_dev_minor (unsigned long long int __dev) { return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); } inline unsigned long long int __gnu_dev_makedev (unsigned int __major, unsigned int __minor) { return ((__minor & 0xff) | ((__major & 0xfff) << 8) | (((unsigned long long int) (__minor & ~0xff)) << 12) | (((unsigned long long int) (__major & ~0xfff)) << 32)); } #define __minor(dev) __gnu_dev_minor(dev) #define __major(dev) __gnu_dev_major(dev) #define __makedev(maj, min) __gnu_dev_makedev(maj, min) int main( int argc, char **argv) { char *prog = argv[0]; char *filename = argv[1]; struct stat st; int rq_rdev; int rc; if (argc != 2) usage(prog); unlink(filename); /* first try block devices */ rq_rdev = __makedev(TEST_MAJOR, TEST_MINOR); rc = mknod(filename, 0700 | S_IFBLK, rq_rdev); if (rc < 0) { fprintf(stderr, "%s: mknod(%s) failed: rc %d: %s\n", prog, filename, errno, strerror(errno)); return 2; } rc = stat(filename, &st); if (rc < 0) { fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n", prog, filename, errno, strerror(errno)); return 3; } if (st.st_rdev != rq_rdev) { fprintf(stderr, "%s: created device other than requested: (%u,%u) instead of (%u,%u)\n", prog, __major(st.st_rdev),__minor(st.st_rdev),__major(rq_rdev),__minor(rq_rdev)); return 4; } if (!S_ISBLK(st.st_mode)) { fprintf(stderr, "%s: created device of different type. Requested block device, got mode %o\n", prog, st.st_mode); return 5; } rc = unlink(filename); if ( rc < 0 ) { fprintf(stderr, "%s: Cannot unlink created device %s, rc %d: %s\n", prog, filename, errno, strerror(errno)); return 6; } /* Second try char devices */ rc = mknod(filename, 0700 | S_IFCHR, rq_rdev); if ( rc < 0 ) { fprintf(stderr, "%s: mknod(%s) failed: rc %d: %s\n", prog, filename, errno, strerror(errno)); return 7; } rc = stat(filename, &st); if ( rc < 0 ) { fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n", prog, filename, errno, strerror(errno)); return 8; } if (st.st_rdev != rq_rdev) { fprintf(stderr, "%s: created device other than requested: (%u,%u) instead of (%u,%u)\n", prog, __major(st.st_rdev),__minor(st.st_rdev),__major(rq_rdev),__minor(rq_rdev)); return 9; } if (!S_ISCHR(st.st_mode)) { fprintf(stderr, "%s: created device of different type. Requested char device, got mode %o\n", prog, st.st_mode); return 10; } rc = unlink(filename); if ( rc < 0 ) { fprintf(stderr, "%s: Cannot unlink created device %s, rc %d: %s\n", prog, filename, errno, strerror(errno)); return 11; } printf("%s: device nodes created correctly\n", prog); return 0; }