/*
 *      $Id: werror.c,v 1.1 1997/01/03 19:42:47 james Exp $
 *      $log$
 */

//static char rcsid[]="$Id: werror.c,v 1.1 1997/01/03 19:42:47 james Exp $";

#include <stdio.h>
#include <fcntl.h>
#include <stdarg.h>

/*** own includes ***/
#include "wtrace.h"

/*** global defines ***/

#include <unistd.h> /* getpid() */
#define GETPID getpid()

/* prototyping */
static int _lockFile(int fh);
static int _unlockFile(int fh);

/******************/
/*** ErrRecover ***/
/******************/
/*
*/
int ErrRecover(char* func1, char* func2, char* formatString, ...) {
  va_list marker;
  static FILE* fh = NULL;

  int fd;

  va_start(marker, formatString);

  if (formatString == NULL) return 1;

  if (fh == NULL) /* if it is not open, open trace-file */
    if ((fd = open("t.log", O_WRONLY | O_CREAT | O_APPEND, 0664)) < 0)
      return 1;
    else if ((fh = fdopen(fd, "at")) < 0) /* get FILE *fh        */
      return 1;                           /* from filedescriptor */
  _lockFile(fd);

  fprintf(fh, "%d ", GETPID);
  fprintf(fh, "%s\t%s\t", func1, func2);
  vfprintf(fh, formatString, marker);
  fprintf(fh, "\n");

  _unlockFile(fd);

  va_end(marker);

  fclose(fh);
  fh = NULL;
  return 0;
}

/********************/
/*** ErrorRecover ***/
/********************/
/*
*/
int ErrorRecover(char* func1, char* func2, int e, char* formatString, ...) {
  va_list marker;
  static FILE* fh = NULL;

  int fd;

  va_start(marker, formatString);

  if (formatString == NULL) return 1;

  if (fh == NULL) /* if it is not open, open trace-file */
    if ((fd = open("t.log", O_WRONLY | O_CREAT | O_APPEND, 0664)) < 0)
      return 1;
    else if ((fh = fdopen(fd, "at")) < 0) /* get FILE *fh        */
      return 1;                           /* from filedescriptor */
  _lockFile(fd);

  fprintf(fh, "%d ", GETPID);
  fprintf(fh, "%s\t%s\t%d\t", func1, func2, e);
  vfprintf(fh, formatString, marker);
  fprintf(fh, "\n");

  _unlockFile(fd);

  va_end(marker);

  fclose(fh);
  fh = NULL;
  return 0;
}

/*****************/
/*** _lockFile ***/
/*****************/
/*
  lock a file from use by other processes
*/
static int _lockFile(int fh) {
  struct flock lock;
  lock.l_type = F_WRLCK;
  lock.l_start = 0;         /* lock the whole file */
  lock.l_whence = SEEK_SET; /* from the beginning  */
  lock.l_len = 0;           /* to the end          */
  return (fcntl(fh, F_SETLKW, &lock));
}

/*******************/
/*** _unlockFile ***/
/*******************/
/*
  release the file lock
*/
static int _unlockFile(int fh) {
  struct flock lock;
  lock.l_type = F_UNLCK;
  lock.l_start = 0;
  lock.l_whence = SEEK_SET;
  lock.l_len = 0;
  return (fcntl(fh, F_SETLKW, &lock));
}
