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)