diff --git Makefile Makefile
index 167225a..369637a 100644
--- Makefile
+++ Makefile
@@ -7,7 +7,7 @@ LD	?= $(CC)
 prefix	= $(PREFIX)
 libdir	= $(prefix)/lib
 
-LOBJS	= syncdir.lo
+LOBJS	= syncdir.lo wrappers.lo
 
 LIBTOOL	= libtool --tag=CC
 
@@ -20,12 +20,20 @@ all:	libsyncdir.la
 testsync: testsync.lo libsyncdir.la
 	$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $< libsyncdir.la
 
-libsyncdir.la: libtool-version-info $(LOBJS)
+libsyncdir.la: wrappers.h libtool-version-info $(LOBJS)
 	$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(LOBJS) -version-info `cat libtool-version-info` -rpath $(libdir)
 
 libtool-version-info:
 	echo $(VERSION) | awk -F. '{ printf "%d:%d:0", $$1, $$2 }' > $@
 
+wrappers.c: trysyscall.c
+	if $(CC) $(CFLAGS) -Wall -Werror -c $< >/dev/null 2>&1; then cp syscall.c $@; else cp dlsym.c $@; fi
+
+wrappers.h: wrappers.c
+	if [ -f trysyscall.o ]; then cp syscall.h $@; else cp dlsym.h $@; fi
+
+syncdir.lo: wrappers.h
+
 install:	all
 	$(LIBTOOL) --mode=install $(BSD_INSTALL_LIB) libsyncdir.la $(DESTDIR)$(libdir)
 
@@ -38,5 +46,6 @@ distrib:
 	$(RM) -r $(TARGET)
 
 clean:
-	$(RM) libtool-version-info core *.o *.lo *.la *.so *.a testsync $(TARGET).tar.gz
+	$(RM) core *.o *.lo *.la *.so *.a testsync $(TARGET).tar.gz
+	$(RM) libtool-version-info wrappers.c wrappers.h
 	$(RM) -r .libs
diff --git dlsym.c dlsym.c
new file mode 100644
index 0000000..47fe21d
--- /dev/null
+++ dlsym.c
@@ -0,0 +1,37 @@
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int checked_noisy = 0;
+static int be_noisy = 0;
+
+int (*real_open)();
+int (*real_close)();
+int (*real_link)();
+int (*real_unlink)();
+int (*real_rename)();
+int (*real_fsync)();
+
+static void log_failure(const char *which)
+{
+  if (be_noisy) fprintf(stderr, "syncdir: can't load system %s()\n", which);
+}
+
+void load_real_syscalls()
+{
+  if (!checked_noisy && getenv("SYNCDIRDEBUG"))
+    be_noisy = 1;
+
+  if (!real_open && !(real_open = dlsym(RTLD_NEXT, "open")))
+    log_failure("open");
+  if (!real_close && !(real_close = dlsym(RTLD_NEXT, "close")))
+    log_failure("close");
+  if (!real_link && !(real_link = dlsym(RTLD_NEXT, "link")))
+    log_failure("link");
+  if (!real_unlink && !(real_unlink = dlsym(RTLD_NEXT, "unlink")))
+    log_failure("unlink");
+  if (!real_rename && !(real_rename = dlsym(RTLD_NEXT, "rename")))
+    log_failure("rename");
+  if (!real_fsync && !(real_fsync = dlsym(RTLD_NEXT, "fsync")))
+    log_failure("fsync");
+}
diff --git dlsym.h dlsym.h
new file mode 100644
index 0000000..d0d4bf2
--- /dev/null
+++ dlsym.h
@@ -0,0 +1,13 @@
+extern int (*real_open)();
+extern int (*real_close)();
+extern int (*real_link)();
+extern int (*real_unlink)();
+extern int (*real_rename)();
+extern int (*real_fsync)();
+
+#define SYS_OPEN(FILE,FLAG,MODE) real_open(FILE, FLAG, MODE)
+#define SYS_CLOSE(FD) real_close(FD)
+#define SYS_LINK(OLD,NEW) real_link(OLD, NEW)
+#define SYS_UNLINK(PATH) real_unlink(PATH)
+#define SYS_RENAME(OLD,NEW) real_rename(OLD, NEW)
+#define SYS_FSYNC(FD) real_fsync(FD)
diff --git syncdir.c syncdir.c
index 2ec2b46..dccb467 100644
--- syncdir.c
+++ syncdir.c
@@ -25,16 +25,12 @@
 #undef open
 #include <unistd.h>
 #include <string.h>
-#include <sys/syscall.h>
 #include <stdio.h>
 #include <errno.h>
 
-#define SYS_OPEN(FILE,FLAG,MODE) syscall(SYS_open, FILE, FLAG, MODE)
-#define SYS_CLOSE(FD) syscall(SYS_close, FD)
-#define SYS_LINK(OLD,NEW) syscall(SYS_link, OLD, NEW)
-#define SYS_UNLINK(PATH) syscall(SYS_unlink, PATH)
-#define SYS_RENAME(OLD,NEW) syscall(SYS_rename, OLD, NEW)
-#define SYS_FSYNC(FD) syscall(SYS_fsync, FD)
+#include "wrappers.h"
+
+int load_real_syscalls(void);
 
 static int fdirsync(const char* filename, unsigned length)
 {
@@ -43,6 +39,7 @@ static int fdirsync(const char* filename, unsigned length)
    * char* dirname = alloca(length+1); */
   int dirfd;
   int retval;
+  load_real_syscalls();
   memcpy(dirname, filename, length);
   dirname[length] = 0;
   if((dirfd = SYS_OPEN(dirname,O_RDONLY,0)) == -1)
@@ -75,7 +72,9 @@ static int fdirsyncfn(const char *filename)
 
 int open(const char *file,int oflag,mode_t mode)
 {
-  int fd = SYS_OPEN(file, oflag, mode);
+  int fd;
+  load_real_syscalls();
+  fd = SYS_OPEN(file, oflag, mode);
   if(fd == -1)
     return fd;
   if (oflag & (O_WRONLY | O_RDWR))
@@ -88,6 +87,7 @@ int open(const char *file,int oflag,mode_t mode)
 
 int link(const char *oldpath,const char *newpath)
 {
+   load_real_syscalls();
    if(SYS_LINK(oldpath,newpath) == -1)
      return -1;
    return fdirsyncfn(newpath);
@@ -95,6 +95,7 @@ int link(const char *oldpath,const char *newpath)
 
 int unlink(const char *path)
 {
+   load_real_syscalls();
    if(SYS_UNLINK(path) == -1)
      return -1;
    return fdirsyncfn(path);
@@ -102,6 +103,7 @@ int unlink(const char *path)
 
 int rename(const char *oldpath,const char *newpath)
 {
+   load_real_syscalls();
    if (SYS_RENAME(oldpath,newpath) == -1)
      return -1;
    if (fdirsyncfn(newpath) == -1)
diff --git syscall.c syscall.c
new file mode 100644
index 0000000..48f32d5
--- /dev/null
+++ syscall.c
@@ -0,0 +1,3 @@
+void load_real_syscalls() {
+  ;
+}
diff --git syscall.h syscall.h
new file mode 100644
index 0000000..9392574
--- /dev/null
+++ syscall.h
@@ -0,0 +1,8 @@
+#include <sys/syscall.h>
+
+#define SYS_OPEN(FILE,FLAG,MODE) syscall(SYS_open, FILE, FLAG, MODE)
+#define SYS_CLOSE(FD) syscall(SYS_close, FD)
+#define SYS_LINK(OLD,NEW) syscall(SYS_link, OLD, NEW)
+#define SYS_UNLINK(PATH) syscall(SYS_unlink, PATH)
+#define SYS_RENAME(OLD,NEW) syscall(SYS_rename, OLD, NEW)
+#define SYS_FSYNC(FD) syscall(SYS_fsync, FD)
diff --git trysyscall.c trysyscall.c
new file mode 100644
index 0000000..a356219
--- /dev/null
+++ trysyscall.c
@@ -0,0 +1,5 @@
+#include <unistd.h>
+
+int main(void) {
+  syscall(5);
+}
