#include #include #include #include #include #include #include #include #include #include #include #include static struct stat parent, current; static int period; static const char *path; static void __attribute__((__noreturn__)) usage(void) { fputs("\nUsage:\n", stderr); fputs("ismounted [-w timeout] folder\n", stderr); fputs(" -w: 1s periodic check until the process ran out of time.\n", stderr); exit(EXIT_SUCCESS); } static void sigHandler(int signo, siginfo_t *si __attribute__((unused)), void /* ucontext_t */ *uap __attribute__((unused))) { switch (signo) { case SIGINFO: printf("Waiting for %s mount. %d seconds remaining.\n", path, period); break; case SIGALRM: /* Timer */ break; default: break; } } int main(int argc, char *argv[]) { int r; char *p_folder = NULL, *a_folder = NULL; /* timer: optional */ struct itimerspec its; timer_t timerid = 0; int ismounted = 0; /* handle options */ int ch; struct option longopts[] = { { "wait", required_argument, &period, 'w' }, { NULL, 0, NULL, 0 } }; opterr = 0; while ((ch = getopt_long(argc, argv, "w:", longopts, NULL)) != -1) { switch (ch) { case 'w': period = atoi(optarg); break; case 0: /* long option */ break; } } if (optind == (argc - 1)) path = argv[optind]; else usage(); /* get real path name */ a_folder = realpath(path, NULL); if (a_folder == NULL) err(EXIT_FAILURE, "Path <%s> unreachable.", path); if (!strcmp("/", a_folder)) { printf("That's the root filesystem dude."); return EXIT_SUCCESS; } /* move to parent */ strncat(a_folder, "/../", PATH_MAX - 1); p_folder = realpath(a_folder, NULL); r = stat(p_folder, &parent); if (r) err(EXIT_FAILURE, "Parent folder of <%s> is unreachable.", path); /* signal */ struct sigaction sa; sa.sa_handler = NULL; sa.sa_sigaction = &sigHandler; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sigfillset(&sa.sa_mask); if (sigaction(SIGINFO, &sa, NULL)) warn("SIGNFO not caught."); if (sigaction(SIGALRM, &sa, NULL)) err(EXIT_FAILURE, "sigaction:ALARM"); /* timer, if set */ if ((period > 0) ) { its.it_interval.tv_sec = 1; its.it_interval.tv_nsec = 0; its.it_value.tv_sec = its.it_interval.tv_sec; its.it_value.tv_nsec = 0; if (timer_create(CLOCK_REALTIME, NULL, &timerid)) err(EXIT_FAILURE,"timer_create failed."); if (timer_settime(timerid, 0, &its, NULL)) err(EXIT_FAILURE, "timer_settime failed."); } /* proceed */ printf("Waiting for folder %s to be mounted ...\n", path); while (1) { r = stat(path, ¤t); if (r) err(EXIT_FAILURE, "Current folder <%s> is unreachable.", path); ismounted = (current.st_dev != parent.st_dev); if (ismounted || (period == 0)) break; /* timer */ pause(); --period; } printf("Folder path %s is %sa mount point.\n", path, (ismounted) ? "" : "*not* " ); if (timerid) timer_delete(timerid); return EXIT_SUCCESS; }