13 #include <sys/socket.h>
18 _(open, int, (const char *, int, ...)) \
19 _(open64, int, (const char *, int, ...)) \
20 _(fopen, FILE *, (const char *, const char *)) \
21 _(freopen, FILE *, (const char *, const char *, FILE *))
23 #define DECL(imp, ret, args) static ret (*real_##imp) args;
27 static void setup(void) __attribute__((constructor));
28 static void import(void)
30 #define IMPORT(imp, ret, args) \
31 real_##imp = (ret (*)args)dlsym(RTLD_NEXT, #imp);
36 #define SA(sa) ((struct sockaddr *)(sa))
38 #define PRESERVING_ERRNO(body) do { \
39 int _err = errno; { body } errno = _err; \
42 static int maybe_connect(const char *fn, int *fdp)
45 struct sockaddr_un sun;
48 if (stat(fn, &st) || !S_ISSOCK(st.st_mode))
51 if (strlen(fn) >= sizeof(sun.sun_path)) {
55 strncpy(sun.sun_path, fn, sizeof(sun.sun_path));
56 sun.sun_family = AF_UNIX;
57 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ||
58 connect(fd, SA(&sun), SUN_LEN(&sun))) {
59 PRESERVING_ERRNO( if (fd >= 0) close(fd); );
66 #define OPEN_VENEER(open) \
67 int open(const char *fn, int how, ...) \
75 { va_start(ap, how); mode = va_arg(ap, int); va_end(ap); } \
76 if (!maybe_connect(fn, &fd)) fd = real_##open(fn, how, mode); \
77 if (fd < 0) return (-1); \
84 FILE *fopen(const char *fn, const char *how)
90 if (!maybe_connect(fn, &fd))
91 fp = real_fopen(fn, how);
92 else if (fd >= 0 && (fp = fdopen(fd, how)) == 0)
93 PRESERVING_ERRNO( close(fd); );
98 FILE *freopen(const char *fn, const char *how, FILE *fp)
103 if (!maybe_connect(fn, &fd))
104 fp = real_freopen(fn, how, fp);
106 if (fflush(fp) || dup2(fd, fileno(fp))) fp = 0;
107 PRESERVING_ERRNO( close(fd); );
113 static void setup(void)