/*
 * Quick test of whether the system allows one to override
 * system-calls made from within system-libraries.
 *
 * On systems with the gcc-toolchain, something like this should work:
 * $ gcc -fPIC -g -c -W -Wall libpreload.c 
 *   && gcc -shared -Wl,-soname,libpreload.so -o libpreload.so libpreload.o
 *   && gcc -W -Wall -L${PWD} preloadtest.c -lpreload 
 *   && LD_LIBRARY_PATH=${PWD} LD_DEBUG=all ./a.out 2>ld_debug.out
 *
 * Linux-systems probably need to add "-ldl".
 *
 * On Solaris, this one might work with the sun toolchain:
 * $  cc -Kpic -g -c libpreload.c
 *    && cc -G -o libpreload.so libpreload.o 
 *    && cc -L${PWD} preloadtest.c -lpreload -lsocket
 *    && LD_LIBRARY_PATH=${PWD} LD_DEBUG=all ./a.out 2>ld_debug.out
 *
 * Make sure you read the comment in the accompanying libpreload.c
 * file also.  
 * Please send the result on new platforms to michaels@inet.no.example.com
 * (remove example.com from the mailaddress).
 *
 * Please include "ld_debug.out" out also, and please run a.out twice;
 * once with LD_DEBUG set as above, and once without, under
 * ktrace/truss/strace, or whatever the name of the syscall-tracer
 * program is on your platform. 
 * Also include output from "uname -a" please.
 *
 * Results so far indicate:
 *    OpenBSD:              ok
 *    NetBSD:               ok
 *    FreeBSD:              ok
 *    Solaris 5.10:         ok
 *    Linux 2.6.15 glibc:   broken
 *    OS X 10.5:            broken
 *
 * -- Michael Shuldman
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>

extern int socket_called;
extern int read_called;
extern int write_called;
extern int open_called;


int
main(argc, argv)
   int argc;
   char *argv[];
{
   int c, err = 0;

   socket_called = 0;
   if ((c = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
      perror("socket()");
      exit(1);
   }
   if (socket_called)
      puts("correct socket(2) called");
   else {
      err = 1;
      puts("wrong socket(2) called"); 
      exit(1); /* if even this one failed, can't expect anything. */
   }

   /* getc(3) would normaly need to call one of the read systemcalls. */
   puts("### type something");
   read_called = 0;
   c = getc(stdin);
   if (read_called)
      puts("correct read(2) called");
   else {
      err = 1;
      puts("wrong read(2) called"); 
   }

   /* fputs(3) would normaly need to call one of the read systemcalls. */
   write_called = 0;
   if (puts("### this should appear on stdout\n") == EOF) {
      perror("puts()");
      exit(1);
   }
   if (write_called)
      puts("correct write(2) called");
   else {
      err = 1;
      puts("wrong write(2) called");
   }

   return err;
}
