1 /* mountpoint.c - Check if a directory is a mountpoint. 2 * 3 * Copyright 2012 Elie De Brauwer <eliedebrauwer (at) gmail.com> 4 5 USE_MOUNTPOINT(NEWTOY(mountpoint, "<1qdx[-dx]", TOYFLAG_BIN)) 6 7 config MOUNTPOINT 8 bool "mountpoint" 9 default y 10 help 11 usage: mountpoint [-q] [-d] directory 12 mountpoint [-q] [-x] device 13 14 -q Be quiet, return zero if directory is a mountpoint 15 -d Print major/minor device number of the directory 16 -x Print major/minor device number of the block device 17 */ 18 19 #define FOR_mountpoint 20 #include "toys.h" 21 22 static void die(char *gripe) 23 { 24 if (!(toys.optflags & FLAG_q)) printf("%s: not a %s\n", *toys.optargs, gripe); 25 26 toys.exitval++; 27 xexit(); 28 } 29 30 void mountpoint_main(void) 31 { 32 struct stat st1, st2; 33 char *arg = *toys.optargs; 34 int quiet = toys.optflags & FLAG_q; 35 36 if (lstat(arg, &st1)) perror_exit_raw(arg); 37 38 if (toys.optflags & FLAG_x) { 39 if (S_ISBLK(st1.st_mode)) { 40 if (!quiet) printf("%u:%u\n", major(st1.st_rdev), minor(st1.st_rdev)); 41 42 return; 43 } 44 die("block device"); 45 } 46 47 // TODO: Ignore the fact a file can be a mountpoint for --bind mounts. 48 if (!S_ISDIR(st1.st_mode)) die("directory"); 49 50 arg = xmprintf("%s/..", arg); 51 xstat(arg, &st2); 52 if (CFG_TOYBOX_FREE) free(arg); 53 54 // If the device is different, it's a mount point. If the device _and_ 55 // inode are the same, it's probably "/". This misses --bind mounts from 56 // elsewhere in the same filesystem, but so does the other one and in the 57 // absence of a spec I guess that's the expected behavior? 58 toys.exitval = !(st1.st_dev != st2.st_dev || st1.st_ino == st2.st_ino); 59 if (toys.optflags & FLAG_d) 60 printf("%u:%u\n", major(st1.st_dev), minor(st1.st_dev)); 61 else if (!quiet) 62 printf("%s is %sa mountpoint\n", *toys.optargs, toys.exitval ? "not " : ""); 63 } 64