My own setlock program written in oldskool C

Following on my previous post on my own setlock code;

I found out that (even after some extra versions), the bash version was simply not solid enough to be used in production. So I’ve written the code in C, where I could use the “fcntl” directly.

The objectives for writing the program, was to extent the regular “setlock” program (from Daemon Tools) to:
– a freely usable code (without Copywright), thus “our own” code
– have an “override” feature (force option)

This program is used in a small framework where it’s architecture was setup in a way where one process periodically updates data. And that this data could be accessed from time to time to be manipulated.

The code:
[my_clearcase_view]kvaes@solaris:~/setlock cat setlock-nsn.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 

int DoLock(int, int, int);
#define read_lock(LockFD) 
                        DoLock(LockFD, F_SETLK, F_RDLCK)
#define read_wait_lock(LockFD) 
                        DoLock(LockFD, F_SETLKW, F_RDLCK)
#define write_lock(LockFD) 
                        DoLock(LockFD, F_SETLK, F_WRLCK)
#define write_wait_lock(LockFD) 
                        DoLock(LockFD, F_SETLKW, F_WRLCK)
#define unlock(LockFD) 
                        DoLock(LockFD, F_SETLK, F_UNLCK)

pid_t PidLock(int, int);
#define readlocked(LockFD) 
                        PidLock(LockFD, F_RDLCK)
#define writelocked(LockFD) 
                        PidLock(LockFD, F_WRLCK)

int
main ( int argc, char *argv[] ){
  int LockFD;
  int EXIT;

  if ( argc  0 ) 
          {
            EXIT=kill(PID,SIGTERM);
            if ( EXIT != 0 )
            {
              printf("Error while trying to kill pid $d.n", PID);
              exit(errno);
            } 
            EXIT=unlock(LockFD);
            if ( EXIT != 0 )
            {
              printf("Error while trying to unlock.n");
              exit(errno);
            }
          }
          EXIT=write_lock(LockFD);
          FOUND=1;
        }
      }
      MATCHES = strcmp( argv[3], "read" );
      if ( MATCHES == 0 )
      {
        TYPE=2;
        MATCHES = strcmp( argv[2], "wait" );
        if ( MATCHES == 0 )
        {
          EXIT=read_wait_lock(LockFD);
          FOUND=1;
        }
        MATCHES = strcmp( argv[2], "nowait" );
        if ( MATCHES == 0 )
        {
          EXIT=read_lock(LockFD);
          FOUND=1;
        }
        MATCHES = strcmp( argv[2], "force" );
        if ( MATCHES == 0 )
        {
          printf("The option %s cannot be used here.n", argv[2]);
          exit(-1);
        }
      }
      if ( FOUND == 0 ) {
        printf("Wrong wait type entered. (%s)n", argv[2]);
        EXIT=-1;
      }
      else
      {
        if ( EXIT == 0 ) 
        {
          EXIT=execute(argc,argv);
          unlock(LockFD);
        }
        else
        {
          printf("Error while trying to use a %s lock.n", argv[2]);
          exit(errno);
        }
      }
    }
  }
  exit(EXIT);
}

int execute(int argc, char *argv[])
{
  int ret = 0;
  char *cmd[argc-4];
  char *prog;

  int i = 0;
  int j = 0;
  for ( i = 0; i < argc; ++i )
  {
    switch ( i ) {
      case 0:
        //executable name
        break;
      case 1:
        //lock file
        break;
      case 2:
        //how do we wait?
        break;
      case 3:
        //read or write?
        break;;
      case 4:
        prog=argv[i];
        cmd[j]=argv[i];
        j++;
        break;
      default:
        cmd[j]=argv[i];
        j++;
        break;
    }       
  }
  cmd[j]=(char *)0;

  ret = execvp(prog, cmd);
  return ret;
}

pid_t PidLock(int LockFD, int type) 
{
  struct flock lock;
  lock.l_type = type;
  lock.l_start = 0;
  lock.l_whence = SEEK_SET;
  lock.l_len = 1;
  if (fcntl(LockFD,F_GETLK,&lock) < 0)
  {
    perror("fcntl"); 
    exit(1);
  }
  if (lock.l_type == F_UNLCK) 
  {
    return(0);        
  }
  return(lock.l_pid); 
}
 
int DoLock(int LockFD, int cmd, int type)
{
  struct flock lock;
  lock.l_type = type;
  lock.l_start = 0;
  lock.l_whence = SEEK_SET;
  lock.l_len = 1;
  return(fcntl(LockFD, cmd, &lock));
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.