#include #include #include #include #include #include #include #define PRNT_OPER(f) printf("\t" #f ": %p <%s>\n", \ (void *)fp->##f, \ _symdesc((void *)(fp->##f))) #define SYMDESC_FMT "%s (%s)" static const char * _symdesc(void *a) { Dl_info dli; char *s; if (!dladdr(a, &dli)) return dlerror(); if (!(s = malloc(sizeof(SYMDESC_FMT) + strlen(dli.dli_fname) + strlen(dli.dli_sname)))) err(1, "Cannot allocate memory"); sprintf(s, SYMDESC_FMT, dli.dli_sname, dli.dli_fname); return s; } int main(int ac, char *av[]) { struct { enum {F, P, S} type; char *desc; } tl[] = {{F, "file"}, {P, "pipe"}, {S, "socket"}}; register int t; for (t = 0; t < (sizeof(tl) / sizeof(tl[0])); ++t) { FILE *fp = NULL; /* XXX */ switch (tl[t].type) { case F: if (!(fp = fopen("/dev/null", "r"))) /* XXX: Use paths.h */ err(1, "Cannot open %s", "/dev/null"); break; case P: if (!(fp = popen("cat", "w"))) err(1, "Cannot open pipe to %s", "cat"); break; case S: if (!(fp = (fdopen(socket(PF_LOCAL, SOCK_STREAM, 0), "rw")))) err(1, "Cannot create socket"); break; } printf("%s:\n", tl[t].desc); printf("\tcookie: %p\n", fp->_cookie); PRNT_OPER(_close); PRNT_OPER(_read); PRNT_OPER(_seek); PRNT_OPER(_write); } return 0; }