Part of my C program is to output whether two device files are equal (i.e., same kind of device file and same major and minor numbers). It outputted that tty and tty2 are the same device files while I think they are not.
I added code to print out the retrieved major and minor numbers for each file and it printed out different numbers from what I got when I did ls -l /dev/tty and ls -l /dev/tty2. The major and minor numbers printed out for both tty and tty2 are 0 and 6, while using ls, they are 5 and 0 for tty and 4 and 2 for tty2.
I'm new to Linux and C.
I have double-checked the manpage for major() and minor() and it seemed that I used these functions correctly. So, I don't know what went wrong.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#define report_error(x) puts("error")
#define BUFFER_SIZE 1<<16
int main(int argc, char *argv[])
{
struct stat statbuf1;
struct stat statbuf2;
char *fn1;
char *fn2;
if (argc < 3) {
if (argc < 1) {
report_error("no command line");
} else {
report_error("Not enough arguments");
}
}
fn1 = argv[1];
fn2 = argv[2];
if (lstat(fn1, &statbuf1)) {
report_error(strerror(errno));
}
if (lstat(fn2, &statbuf2)) {
report_error(strerror(errno));
}
if (S_ISCHR(statbuf1.st_mode) && S_ISCHR(statbuf2.st_mode)) {
unsigned int major1 = major(statbuf1.st_dev);
unsigned int major2 = major(statbuf2.st_dev);
unsigned int minor1 = minor(statbuf1.st_dev);
unsigned int minor2 = minor(statbuf2.st_dev);
printf("%d %d\n%d %d\n", major1, major2, minor1, minor2);
if (major1 == major2 && minor1 == minor2) {
printf("the two device files are equal\n");
exit(0);
}
}
return 0;
}
st_dev is the ID of device containing file, according to the man page. In other words, the device where the file's name resides. So it's the same as for your /dev directory, as you'll see if you use the stat command from your shell.
You're interested in st_rdev, which is Device ID (if special file) (again, from the man page).
The stat command shows both:
stat /dev/tty /dev/tty1
File: /dev/tty Size: 0 Blocks: 0 IO Block: 4096 character special file Device: 6h/6d Inode: 1035 Links: 1 Device type: 5,0 Access: (0620/crw--w----) Uid: ( 0/ root) Gid: ( 5/ tty)
....
File: /dev/tty1 Size: 0 Blocks: 0 IO Block: 4096 character special file Device: 6h/6d Inode: 1044 Links: 1 Device type: 4,1 Access: (0620/crw--w----) Uid: ( 0/ root) Gid: ( 5/ tty)
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <unistd.h>
int get_char_device(const char *name,
unsigned *dev_major, unsigned *dev_minor)
{
struct stat buf;
if (stat(name, &buf)) {
perror(name);
return 1;
}
if (!S_ISCHR(buf.st_mode)) {
fprintf(stderr, "%s: not a char device\n", name);
return 1;
}
*dev_major = major(buf.st_rdev);
*dev_minor = minor(buf.st_rdev);
return 0;
}
int main(void)
{
unsigned int major1, minor1, major2, minor2;
if (get_char_device("/dev/tty1", &major1, &minor1) ||
get_char_device("/dev/tty2", &major2, &minor2)) {
return 1;
}
printf("%d %d\n%d %d\n", major1, major2, minor1, minor2);
if (major1 == major2 && minor1 == minor2) {
puts("the two device files are equal");
return 1;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With