/* source: xiolockfile.c */
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */
/* Published under the GNU General Public License V.2, see file COPYING */

/* this file contains socats explicit locking mechanisms */

#include "xiosysincludes.h"

#include "compat.h"
#include "mytypes.h"
#include "error.h"
#include "utils.h"
#include "sysutils.h"

#include "sycls.h"

#include "xio.h"
#include "xiolockfile.h"


/* returns 0 if it could create lock; 1 if the lock exists; -1 on error */
int xiogetlock(const char *lockfile) {
   char *s;
   struct stat strat;
   int fd;
   pid_t pid;
   char pidbuf[3*sizeof(pid_t)+1];
   size_t bytes;

   if (Lstat(lockfile, &strat) == 0) {
      return 1;
   }
   switch (errno) {
   case ENOENT: break;
   default:
      Error3("Lstat(\"%s\", %p): %s", lockfile, &strat, strerror(errno));
      return -1;
   }
   /* in this moment, the file did not exist */

   if ((s = Malloc(strlen(lockfile)+8)) == NULL) {
      errno = ENOMEM;
      return -1;
   }
   strcpy(s, lockfile);
   strcat(s, ".XXXXXX");

   if ((fd = Mkstemp(s)) < 0) {
      Error2("mkstemp(\"%s\"): %s", s, strerror(errno));
      return -1;
   }
  
   pid = Getpid();
   bytes = sprintf(pidbuf, F_pid"\n", pid);
   if (writefull(fd, pidbuf, bytes) < 0) {
      Error4("write(%d, %p, "F_Zu"): %s", fd, pidbuf, bytes, strerror(errno));
      return -1;
   }
   Fchmod(fd, 0644);
   Close(fd);

   if (Link(s, lockfile) < 0) {
      int _errno = errno;
      Error3("link(\"%s\", \"%s\"): %s", s, lockfile, strerror(errno));
      Unlink(s);
      errno = _errno;
      return -1;
   }
   Unlink(s);

   return 0;
}

int xiounlock(const char *lockfile) {
   return Unlink(lockfile);
}


/* returns 0 when it could create lock, or -1 on error */
int xiowaitlock(const char *lockfile, struct timespec *intervall) {
   int rc;
   int level = E_NOTICE;	/* first print a notice */

   while ((rc = xiogetlock(lockfile)) == 1) {
      Msg1(level, "waiting for lock \"%s\"", lockfile);
      level = E_INFO;		/* afterwards only make info */
      Nanosleep(intervall, NULL);
   }
   return rc;
}


/* returns 0 when it could obtain lock or the lock is not valid
   (lockfile==NULL), 1 if it could not obtain the lock, or -1 on error */
int xiolock(xiolock_t *lock) {
   int result;

   if (lock->lockfile == NULL) {
      return 0;
   }
   if (lock->waitlock) {
      result = xiowaitlock(lock->lockfile, &lock->intervall);
   } else {
      result = xiogetlock(lock->lockfile);
   }
   if (result == 0) {
      Info1("obtained lock \"%s\"", lock->lockfile);
   }
   return result;
}


int xiofiledroplock(xiofile_t *xfd) {
   if (xfd->tag == XIO_TAG_DUAL) {
      xiofiledroplock((xiofile_t *)xfd->dual.stream[0]);
      xiofiledroplock((xiofile_t *)xfd->dual.stream[1]);
   } else {
      xfd->stream.havelock = false;
   }
   return 0;
}
