Customizing I/O of CoverageScanner library

Custom I/O using C file access

The following example shows how to generate the execution report using the standard C file API.

To compile the example on Microsoft® Windows:

cscl customiofile.c

To compile the example on Linux™ or macOS:

csgcc customiofile.c -o customiofile

Source code:

#include <stdio.h>
#include <string.h>
#define VERBOSE 1

static int csfputs(const char *s, void *stream)
{
#if VERBOSE
  fprintf(stderr,"csfputs:%s\n",s);
#endif
  return fputs(s, (FILE *)stream);
}

static void *csfopenappend(const char *path)
{
#if VERBOSE
  fprintf(stderr,"csfopenappend:%s\n",path);
#endif
  return (void*)fopen(path,"a+");
}

static void *csfopenread(const char *path)
{
#if VERBOSE
  fprintf(stderr,"csfopenread:%s\n",path);
#endif
  return (void*)fopen(path,"r");
}

static void *csfopenwrite(const char *path)
{
#if VERBOSE
  fprintf(stderr,"csfopenwrite:%s\n",path);
#endif
  return (void*)fopen(path,"w");
}

static char *csfgets(char *s, int size, void *stream)
{
  char * ret;
  ret = fgets(s, size, (FILE *)stream);
#if VERBOSE
  fprintf(stderr,"csfgets:%s\n",s);
#endif
  return ret;
}

static int csremove(const char *filename)
{
#if VERBOSE
  fprintf(stderr,"csremove:%s\n",filename);
#endif
  return remove(filename);
}

static int csfclose(void *fp)
{
#if VERBOSE
  fprintf(stderr,"csfclose\n");
#endif
  return fclose((FILE*)fp);
}

int main()
{
  char location[256];
  int lg_location;

  printf(".csexe file name (without extension}:"); fflush(stdout);
  fgets(location,sizeof(location),stdin);
  lg_location=strlen(location);
  if (lg_location)
    location[lg_location-1]='\0'; // strip \n
#ifdef __COVERAGESCANNER__
  __coveragescanner_set_custom_io( csfgets,
      csfputs,
      csfopenappend,
      csfopenread,
      csfopenwrite,
      csfclose,
      csremove);
  __coveragescanner_install(location);
#endif
}

Custom I/O using SFTP protocol

The following example shows how to generate the execution report directly on a SFTP server. The SFTP server is part of SSH v2 and is available on most Unix platforms. On Windows, a free SSH server can be downloaded from freeSSHd and freeFTPd.

To compile the example on Windows:

  1. Download libSSH2 from libssh2. Generate the library, and set the environment variable LIBSSH2 to the location of the libSSH2 source code.
  2. To compile the example:
    cscl %LIBSSH2%\win32\debug_dll\libssh2.lib -DWIN32 --cs-libgen=/MTd
         /MTd -I %LIBSSH2%\include ws2_32.lib customiosftp.c
  3. Execute custom_io_sftp.exe.

To compile the example on Linux™:

  1. Install the development package of libssh2.
  2. To compile the example:
    csgcc -lssh2 customiosftp.c -o customiosftp
  3. Execute custom_io_sftp.

Source code:

*
    #define VERBOSE 1

    #ifdef WIN32
    # include <winsock2.h>
    #define LIBSSH2_WIN32
    #define LIBSSH2_API
    #else
    #include <unistd.h>
    # include <sys/socket.h>
    # include <netinet/in.h>
    #include <arpa/inet.h>
    #endif
    #include <libssh2.h>
    #include <libssh2_sftp.h>

    #include <sys/types.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdio.h>
    #include <ctype.h>

    static LIBSSH2_SESSION *session=NULL;
    static LIBSSH2_SFTP *sftp_session=NULL;
    static int sock=0;

    static void extract_location(const char *location, char *server, char *user, char*passwd, char *file)
    {
      int i,j;
      int lg_location;
      lg_location=strlen(location);
      for (i=0;i<lg_location;i++)
      {
        if (location[i]=='\n')
          break;
        server[i]=location[i];
      }
      server[i]='\0';
      i++;

      for (j=0;i<lg_location;i++,j++)
      {
        if (location[i]=='\n')
          break;
        user[j]=location[i];
      }
      user[j]='\0';
      i++;

      for (j=0;i<lg_location;i++,j++)
      {
        if (location[i]=='\n')
          break;
        passwd[j]=location[i];
      }
      passwd[j]='\0';
      i++;

      for (j=0;i<lg_location;i++,j++)
      {
        if (location[i]=='\0')
          break;
        file[j]=location[i];
      }
      file[j]='\0';
    }

    static void close_sftp_session()
    {
      if (sftp_session)
        libssh2_sftp_shutdown(sftp_session);
      sftp_session=NULL;

      if (session)
      {
        libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
        libssh2_session_free(session);
      }
      session=NULL;

      if (sock)
      {
    #ifdef WIN32
        Sleep(1000);
        closesocket(sock);
    #else
        sleep(1);
        close(sock);
    #endif
      }
      sock=0;
    }

    static  int open_sftp_session(const char *server,const char *user,const char *passwd)
    {
      struct sockaddr_in sin;
      int rc;

      sock = socket(AF_INET, SOCK_STREAM, 0);

      sin.sin_family = AF_INET;
      sin.sin_port = htons(22);
      sin.sin_addr.s_addr = inet_addr(server);
      if (connect(sock, (struct sockaddr*)(&sin),
            sizeof(struct sockaddr_in)) != 0)
      {
        close_sftp_session();
        return 0;
      }

      /* Create a session instance
      */
      session = libssh2_session_init();
      if(!session)
      {
        close_sftp_session();
        return 0;
      }

      /* ... start it up. This will trade welcome banners, exchange keys,
       * and setup crypto, compression, and MAC layers
       */
      rc = libssh2_session_startup(session, sock);
      if(rc)
      {
        close_sftp_session();
        return 0;
      }

      libssh2_session_set_blocking(session, 1);

      if (libssh2_userauth_password(session, user, passwd))
      {
        close_sftp_session();
        return 0;
      }

      sftp_session = libssh2_sftp_init(session);

      if (!sftp_session)
      {
        close_sftp_session();
        return 0;
      }
      return 1;
    }

    static int csfputs(const char *s, void *stream)
    {
    #if VERBOSE
      fprintf(stderr,"csfputs:%s\n",s);
    #endif
      return libssh2_sftp_write((LIBSSH2_SFTP_HANDLE*)stream,s,strlen(s));
    }

    static void *csfopenappend(const char *location)
    {
      LIBSSH2_SFTP_HANDLE *handle;
      char server[1024];
      char user[1024];
      char passwd[1024];
      char file[1024];
      LIBSSH2_SFTP_ATTRIBUTES attrs;

      extract_location(location,server,user,passwd,file);
    #if VERBOSE
      fprintf(stderr,"csfopenappend %s:%s:%s\n",server,user,file);
    #endif
      if (open_sftp_session(server,user,passwd))
      {
        handle = libssh2_sftp_open(sftp_session, file, LIBSSH2_FXF_CREAT|LIBSSH2_FXF_WRITE,
            LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
            LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH );
      }
      else
        return NULL;

      if (handle)
      {
        if (libssh2_sftp_fstat(handle,&attrs)==0)
        { /* Go to the end of the file */
          libssh2_sftp_seek(handle,attrs.filesize);
        }
      }
      return handle;
    }

    static void *csfopenread(const char *location)
    {
      char server[1024];
      char user[1024];
      char passwd[1024];
      char file[1024];

      extract_location(location,server,user,passwd,file);
    #if VERBOSE
      fprintf(stderr,"csfopenread %s:%s:%s\n",server,user,file);
    #endif
      if (open_sftp_session(server,user,passwd))
        return (void*)  libssh2_sftp_open(sftp_session, file, LIBSSH2_FXF_READ, 0);
      else
        return NULL;
    }

    static void *csfopenwrite(const char *location)
    {
      char server[1024];
      char user[1024];
      char passwd[1024];
      char file[1024];

      extract_location(location,server,user,passwd,file);
    #if VERBOSE
      fprintf(stderr,"csfopenwrite %s:%s:%s\n",server,user,file);
    #endif
      if (open_sftp_session(server,user,passwd))
        return (void*)  libssh2_sftp_open(sftp_session, file, LIBSSH2_FXF_CREAT|LIBSSH2_FXF_WRITE,
            LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
            LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH );
      else
        return NULL;
    }

    static char *csfgets(char *s, int size, void *stream)
    {
      size_t ss;
      ss = libssh2_sftp_read((LIBSSH2_SFTP_HANDLE*)stream,s,size-1);
      if (ss)
      {
        s[ss]='\0';
    #if VERBOSE
        fprintf(stderr,"csfgets:%s\n",s);
    #endif
        return s;
      }
      else
        return NULL;
    }

    static int csremove(const char *location)
    {
      int ret;
      char server[1024];
      char user[1024];
      char passwd[1024];
      char file[1024];

      extract_location(location,server,user,passwd,file);
    #if VERBOSE
      fprintf(stderr,"csremove %s:%s:%s\n",server,user,file);
    #endif
      if (open_sftp_session(server,user,passwd))
      {
        ret = libssh2_sftp_unlink(sftp_session,file);
        close_sftp_session();
        return ret;
      }
      else
        return -1;
    }

    static int csfclose(void *fp)
    {
    #if VERBOSE
      fprintf(stderr,"csfclose\n");
    #endif
      return libssh2_sftp_close((LIBSSH2_SFTP_HANDLE*)fp);
    }

    int main()
    {
      char location[1024];
      char tmp[1024];
    #ifdef WIN32
      WSADATA wsadata;

      WSAStartup(WINSOCK_VERSION, &wsadata);
    #endif

      location[0]='\0';

      printf("server IP:"); fflush(stdout);
      fgets(tmp,sizeof(tmp),stdin);
      strcat(location,tmp);

      printf("user:"); fflush(stdout);
      fgets(tmp,sizeof(tmp),stdin);
      strcat(location,tmp);

      printf("passwd:"); fflush(stdout);
      fgets(tmp,sizeof(tmp),stdin);
      strcat(location,tmp);

      printf(".csexe file name (without extension}:"); fflush(stdout);
      fgets(tmp,sizeof(tmp),stdin);
      strcat(location,tmp);

      location[strlen(location)-1]='\0';

    #ifdef __COVERAGESCANNER__
      __coveragescanner_set_custom_io( csfgets,
          csfputs,
          csfopenappend,
          csfopenread,
          csfopenwrite,
          csfclose,
          csremove);
      __coveragescanner_install(location);
    #endif
    }