Created
June 3, 2017 09:27
-
-
Save fonlang/eecebd98f6867351b92f340e87dd8f6e to your computer and use it in GitHub Desktop.
linux inotify api example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/inotify.h> | |
#include <limits.h> | |
#include "tlpi_hdr.h" | |
static void | |
displayInotifyEvent(struct inotify_event *i) | |
{ | |
printf(" wd=%2d; ", i->wd); | |
if (i->cookie > 0) | |
printf("cookie=%4d; ", i->cookie); | |
printf("mask = "); | |
if (i->mask & IN_ACCESS) printf("IN_ACCESS"); | |
if (i->mask & IN_ATTRIB) printf("IN_ATTRIB "); | |
if (i->mask & IN_CLOSE_NOWRITE) printf("IN_CLOSE_NOWRITE "); | |
if (i->mask & IN_CLOSE_WRITE) printf("IN_CLOSE_WRITE "); | |
if (i->mask & IN_CREATE) printf("IN_CREATE "); | |
if (i->mask & IN_DELETE) printf("IN_DELETE "); | |
if (i->mask & IN_DELETE_SELF) printf("IN_DELETE_SELF "); | |
if (i->mask & IN_IGNORED) printf("IN_IGNORED "); | |
if (i->mask & IN_ISDIR) printf("IN_ISDIR "); | |
if (i->mask & IN_MODIFY) printf("IN_MODIFY "); | |
if (i->mask & IN_MOVE_SELF) printf("IN_MOVE_SELF "); | |
if (i->mask & IN_MOVED_FROM) printf("IN_MOVED_FROM "); | |
if (i->mask & IN_MOVED_TO) printf("IN_MOVED_TO "); | |
if (i->mask & IN_OPEN) printf("IN_OPEN "); | |
if (i->mask & IN_Q_OVERFLOW) printf("IN_Q_OVERFLOW "); | |
if (i->mask & IN_UNMOUNT) printf("IN_UNMOUNT "); | |
printf("\n"); | |
if (i->len > 0) | |
printf(" name = %s\n", i->name); | |
} | |
#define BUF_LEN (10 * (sizeof(struct inotify_event) + NAME_MAX + 1)) | |
int | |
main(int argc, char *argv[]) | |
{ | |
int inotifyFd, wd, j; | |
char buf[BUF_LEN] __attribute__ ((aligned(8))); | |
ssize_t numRead; | |
char *p; | |
struct inotify_event *event; | |
if (argc < 2 || strcmp(argv[1], "--help") == 0) | |
usageErr("%s pathname...\n", argv[0]); | |
inotifyFd = inotify_init(); | |
if (inotifyFd == -1) | |
errExit("inotify_init"); | |
for (j = 1; j < argc; j++) { | |
wd = inotify_add_watch(inotifyFd, argv[j], IN_ALL_EVENTS); | |
if (wd == -1) | |
errExit("inotify_add_watch"); | |
printf("Watching %s using wd %d\n", argv[j], wd); | |
} | |
for (;;) { | |
numRead = read(inotifyFd, buf, BUF_LEN); | |
if (numRead == 0) | |
fatal("read() from inotify fd returned 0!"); | |
if (numRead == -1) | |
errExit("read"); | |
printf("Read %ld bytes from inotify fd\n", (long) numRead); | |
for (p = buf; p < buf + numRead; ) { | |
event = (struct inotify_event *) p; | |
displayInotifyEvent(event); | |
p += sizeof(struct inotify_event) + event->len; | |
} | |
} | |
exit(EXIT_SUCCESS); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static char *ename[] = { | |
/* 0 */ "", | |
/* 1 */ "EPERM", "ENOENT", "ESRCH", "EINTR", "EIO", "ENXIO", | |
/* 7 */ "E2BIG", "ENOEXEC", "EBADF", "ECHILD", | |
/* 11 */ "EAGAIN/EWOULDBLOCK", "ENOMEM", "EACCES", "EFAULT", | |
/* 15 */ "ENOTBLK", "EBUSY", "EEXIST", "EXDEV", "ENODEV", | |
/* 20 */ "ENOTDIR", "EISDIR", "EINVAL", "ENFILE", "EMFILE", | |
/* 25 */ "ENOTTY", "ETXTBSY", "EFBIG", "ENOSPC", "ESPIPE", | |
/* 30 */ "EROFS", "EMLINK", "EPIPE", "EDOM", "ERANGE", | |
/* 35 */ "EDEADLK/EDEADLOCK", "ENAMETOOLONG", "ENOLCK", "ENOSYS", | |
/* 39 */ "ENOTEMPTY", "ELOOP", "", "ENOMSG", "EIDRM", "ECHRNG", | |
/* 45 */ "EL2NSYNC", "EL3HLT", "EL3RST", "ELNRNG", "EUNATCH", | |
/* 50 */ "ENOCSI", "EL2HLT", "EBADE", "EBADR", "EXFULL", "ENOANO", | |
/* 56 */ "EBADRQC", "EBADSLT", "", "EBFONT", "ENOSTR", "ENODATA", | |
/* 62 */ "ETIME", "ENOSR", "ENONET", "ENOPKG", "EREMOTE", | |
/* 67 */ "ENOLINK", "EADV", "ESRMNT", "ECOMM", "EPROTO", | |
/* 72 */ "EMULTIHOP", "EDOTDOT", "EBADMSG", "EOVERFLOW", | |
/* 76 */ "ENOTUNIQ", "EBADFD", "EREMCHG", "ELIBACC", "ELIBBAD", | |
/* 81 */ "ELIBSCN", "ELIBMAX", "ELIBEXEC", "EILSEQ", "ERESTART", | |
/* 86 */ "ESTRPIPE", "EUSERS", "ENOTSOCK", "EDESTADDRREQ", | |
/* 90 */ "EMSGSIZE", "EPROTOTYPE", "ENOPROTOOPT", | |
/* 93 */ "EPROTONOSUPPORT", "ESOCKTNOSUPPORT", | |
/* 95 */ "EOPNOTSUPP/ENOTSUP", "EPFNOSUPPORT", "EAFNOSUPPORT", | |
/* 98 */ "EADDRINUSE", "EADDRNOTAVAIL", "ENETDOWN", "ENETUNREACH", | |
/* 102 */ "ENETRESET", "ECONNABORTED", "ECONNRESET", "ENOBUFS", | |
/* 106 */ "EISCONN", "ENOTCONN", "ESHUTDOWN", "ETOOMANYREFS", | |
/* 110 */ "ETIMEDOUT", "ECONNREFUSED", "EHOSTDOWN", "EHOSTUNREACH", | |
/* 114 */ "EALREADY", "EINPROGRESS", "ESTALE", "EUCLEAN", | |
/* 118 */ "ENOTNAM", "ENAVAIL", "EISNAM", "EREMOTEIO", "EDQUOT", | |
/* 123 */ "ENOMEDIUM", "EMEDIUMTYPE", "ECANCELED", "ENOKEY", | |
/* 127 */ "EKEYEXPIRED", "EKEYREVOKED", "EKEYREJECTED", | |
/* 130 */ "EOWNERDEAD", "ENOTRECOVERABLE", "ERFKILL", "EHWPOISON" | |
}; | |
#define MAX_ENAME 133 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdarg.h> | |
#include "error_functions.h" | |
#include "tlpi_hdr.h" | |
#include "ename.c.inc" | |
#ifdef __GNUC__ | |
__attribute__ ((__noreturn__)) | |
#endif | |
static void | |
terminate(Boolean useExit3) | |
{ | |
char *s; | |
s = getenv("EF_DUMPCORE"); | |
if (s != NULL && *s != '\0') | |
abort(); | |
else if (useExit3) | |
exit(EXIT_FAILURE); | |
else | |
_exit(EXIT_FAILURE); | |
} | |
static void | |
outputError(Boolean useErr, int err, Boolean flushStdout, | |
const char *format, va_list ap) | |
{ | |
#define BUF_SIZE 500 | |
char buf[BUF_SIZE], userMsg[BUF_SIZE], errText[BUF_SIZE]; | |
vsnprintf(userMsg, BUF_SIZE, format, ap); | |
if (useErr) | |
snprintf(errText, BUF_SIZE, " [%s %s]", | |
(err > 0 && err <= MAX_ENAME) ? | |
ename[err] : "?UNKNOWN?", strerror(err)); | |
else | |
snprintf(errText, BUF_SIZE, ":"); | |
snprintf(buf, BUF_SIZE, "ERROR%s %s\n", errText, userMsg); | |
if (flushStdout) | |
fflush(stdout); | |
fputs(buf, stderr); | |
fflush(stderr); | |
} | |
void | |
errMsg(const char *format, ...) | |
{ | |
va_list argList; | |
int savedErrno; | |
savedErrno = errno; | |
va_start(argList, format); | |
outputError(TRUE, errno, TRUE, format, argList); | |
va_end(argList); | |
errno = savedErrno; | |
} | |
void | |
errExit(const char *format, ...) | |
{ | |
va_list argList; | |
va_start(argList, format); | |
outputError(TRUE, errno, TRUE, format, argList); | |
va_end(argList); | |
terminate(TRUE); | |
} | |
void | |
err_exit(const char *format, ...) | |
{ | |
va_list argList; | |
va_start(argList, format); | |
outputError(TRUE, errno, FALSE, format, argList); | |
va_end(argList); | |
terminate(FALSE); | |
} | |
void | |
errExitEN(int errnum, const char *format, ...) | |
{ | |
va_list argList; | |
va_start(argList, format); | |
outputError(TRUE, errnum, TRUE, format, argList); | |
va_end(argList); | |
terminate(TRUE); | |
} | |
void | |
fatal(const char *format, ...) | |
{ | |
va_list argList; | |
va_start(argList, format); | |
outputError(FALSE, 0, TRUE, format, argList); | |
va_end(argList); | |
terminate(TRUE); | |
} | |
void | |
usageErr(const char *format, ...) | |
{ | |
va_list argList; | |
fflush(stdout); | |
fprintf(stderr, "Usage: "); | |
va_start(argList, format); | |
vfprintf(stderr, format, argList); | |
va_end(argList); | |
fflush(stderr); | |
exit(EXIT_FAILURE); | |
} | |
void | |
cmdLineErr(const char *format, ...) | |
{ | |
va_list argList; | |
fflush(stdout); | |
fprintf(stderr, "Command-line usage error: "); | |
va_start(argList, format); | |
vfprintf(stderr, format, argList); | |
va_end(argList); | |
fflush(stderr); | |
exit(EXIT_FAILURE); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ERROR_FUNCTIONS_H | |
#define ERROR_FUNCTIONS_H | |
void errMsg(const char *format, ...); | |
#ifdef __GUNC__ | |
#define NORETURN __attribute__ ((__noreturn__)) | |
#else | |
#define NORETURN | |
#endif | |
void errExit(const char *format, ...) NORETURN ; | |
void err_exit(const char *format, ...) NORETURN ; | |
void errExitEN(int errnum, const char *format, ...) NORETURN ; | |
void fatal(const char *format, ...) NORETURN ; | |
void usageErr(const char *format, ...) NORETURN ; | |
void cmdLineErr(const char *format, ...) NORETURN ; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <limits.h> | |
#include <errno.h> | |
#include "get_num.h" | |
static void | |
gnFail(const char*fname, const char *msg, const char *arg, const char *name) | |
{ | |
fprintf(stderr, "%s error", fname); | |
if (name != NULL) | |
fprintf(stderr, " (in %s)", name); | |
fprintf(stderr, ": %s\n", msg); | |
if (arg != NULL && *arg != '\0') | |
fprintf(stderr, " offending text: %s\n", arg); | |
exit(EXIT_FAILURE); | |
} | |
static long | |
getNum(const char *fname, const char *arg, int flags, const char *name) | |
{ | |
long res; | |
char *endptr; | |
int base; | |
if (arg == NULL || *arg == '\0') | |
gnFail(fname, "null or empty string", arg, name); | |
base = (flags & GN_ANY_BASE) ? 0 : (flags & GN_BASE_8) ? 8 : | |
(flags & GN_BASE_16) ? 16 : 10; | |
errno = 0; | |
res = strtol(arg, &endptr, base); | |
if (errno != 0) | |
gnFail(fname, "strtol() failed", arg, name); | |
if (*endptr != '\0') | |
gnFail(fname, "nonnumeric characters", arg, name); | |
if ((flags & GN_NONNEG) && res < 0) | |
gnFail(fname, "negative value not allowed", arg, name); | |
if ((flags & GN_GT_0) && res <= 0) | |
gnFail(fname, "value must be > 0", arg, name); | |
return res; | |
} | |
long | |
getLong(const char *arg, int flags, const char *name) | |
{ | |
return getNum("getLong", arg, flags, name); | |
} | |
int | |
getInt(const char *arg, int flags, const char *name) | |
{ | |
long res; | |
res = getNum("getInt", arg, flags, name); | |
if (res > INT_MAX || res < INT_MIN) | |
gnFail("getInt", "integer out of range", arg, name); | |
return (int) res; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef GET_NUM_H | |
#define GET_NUM_H | |
#define GN_NONNEG 01 | |
#define GN_GT_0 02 | |
#define GN_ANY_BASE 0100 | |
#define GN_BASE_8 0200 | |
#define GN_BASE_16 0400 | |
long getLong(const char *arg, int flags, const char *name); | |
int getInt(const char *arg, int flags, const char *name); | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef TLPI_HDR_H | |
#define TLPI_HDR_H | |
#include <sys/types.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <string.h> | |
#include "get_num.h" | |
#include "error_functions.h" | |
#ifdef TRUE | |
#undef TRUE | |
#endif | |
#ifdef FALSE | |
#undef FALSE | |
#endif | |
typedef enum { FALSE, TRUE } Boolean; | |
#define min(m, n) ((m) < (n) ? (m) : (n)) | |
#define max(m, n) ((m) > (n) ? (m) : (n)) | |
#if defined(__sgi) | |
typedef int socklen_t; | |
#endif | |
#if defined(__sun) | |
#include <sys/file.h> | |
#endif | |
#if ! defined(O_ASYNC) && defined(FASYNC) | |
#define O_ASYNC FASYNC | |
#endif | |
#if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS) | |
#define MAP_ANONYMOUS MAP_ANON | |
#endif | |
#if ! defined(O_SYNC) && defined(O_FASYNC) | |
#define O_SYNC O_FSYNC | |
#endif | |
#if defined(__FreeBSD__) | |
#define sival_int sigval_int | |
#define sival_ptr sigval_ptr | |
#endif | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment