#include "ruby.h"

#include <stdio.h>
#include <string.h>
#include <errno.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/stat.h>


static const char* Revision = "$Id: _filelock.c,v 1.2 2000/03/23 10:09:10 cle Exp $";


/*** Declaration of helper variables ***/

static ID id_pid, id_error;

/*** Declaration of Function ***/

static VALUE create_lock _((VALUE self));

/*** Declaration of Export Functions ***/

void Init_flock _((void));


/*** Implementation of Function ***/

static VALUE
#ifdef HAVE_PROTOTYPES
create_lock(VALUE self)
#else
create_lock(self)
     VALUE self;
#endif
{
  FILE* fp;
  VALUE filename;
  struct stat st;
  
  filename = rb_iv_get(self, "@lockfilename");
  
  if (stat(RSTRING(filename)->ptr, &st) >= 0) return Qfalse;
  
  fp = fopen(RSTRING(filename)->ptr, "w");
  if (fp == NULL)
    rb_raise(rb_const_get(self, id_error), strerror(errno));

  fprintf(fp, "%ld", NUM2LONG(rb_funcall(rb_mProcess, id_pid, 0, 0)));
  fclose(fp);

  if (stat(RSTRING(filename)->ptr, &st) < 0)
    rb_raise(rb_const_get(self, id_error), strerror(errno));
  
  return rb_iv_set(self, "@locked", INT2FIX(st.st_mtime));
} /* end of create_lock */


/*** Extension Initilization Function ***/

void
Init__filelock()
{
  /**
   ** This function will automatically called by ruby. It will announce
   ** all C functions, that are useable in ruby.
   */
  
  VALUE mFileLock = rb_const_get(rb_cObject, rb_intern("FileLock"));
  VALUE cLockFile = rb_const_get(mFileLock, rb_intern("LockFile"));

  rb_define_private_method(cLockFile, "createLock", create_lock, 0);

  id_pid = rb_intern("pid");
  id_error = rb_intern("CreateLockError");
}
