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