| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- #include <stdlib.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <limits.h>
- #include <unistd.h>
- #include <getopt.h>
- #include <locale.h>
- #include <err.h>
- #include <string.h>
- #include <errno.h>
- #include <getopt.h>
- #include <signal.h>
- static struct stat parent, current;
- static int period;
- 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;
- 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* " );
- return EXIT_SUCCESS;
- }
|