File: locks.C

package info (click to toggle)
speaker 1.0.1-3
  • links: PTS
  • area: main
  • in suites: potato
  • size: 264 kB
  • ctags: 174
  • sloc: cpp: 1,521; tcl: 786; makefile: 91; sh: 22
file content (138 lines) | stat: -rw-r--r-- 3,189 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//************************************************************
//  locks.C - source file for creation and removal of port 
//             locks
//************************************************************
#include "incall.h"

Locks::Locks()
{
   PortLocked = 0;
   LockFileName = NULL;
}

Locks::~Locks()
{
   if (LockFileName)
   {
      RemoveLockFile();
      delete LockFileName;
   }
}

void Locks::Init(ConfigInfo* conf)
{
   int  i;
   LockFileName = new char[strlen(conf->LockPath) + 
                           7 + strlen(conf->SerialPort)];

   strcpy(LockFileName, conf->LockPath);
   strcat(LockFileName, "/LCK..");
   for (i=strlen(conf->SerialPort)-1; i > 0 && conf->SerialPort[i]!='/'; i--);
   i++;
   
   strcat(LockFileName, &(conf->SerialPort[i]));
}

// Attempts to create a lock file for the specified ttyS.
// returns:
//  1 - success
//  0 - device is locked by another process
//  -1 - Something is really screwed (permissions?)
int Locks::MakeLockFile()
{
   char LockBuf[MAXPATHLEN];
   int  fd, procID;

   if (PortLocked) return 1;

   // If you use NFS, see man open for different implementation,
   // I'm toooooo lazy to do it the RIGHT way. Sorry.
   fd = open( LockFileName, O_WRONLY | O_CREAT | O_EXCL, 
              S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

   if (fd == -1)
   {
      // Something did not work
      if (errno != EEXIST)
         return -1; // Go, figure....

      // File exists, the port may be locked by another process
      // Check if the process exist...
      fd = open( LockFileName, O_RDONLY );
      if (fd == -1) return 0;

      if (read( fd, LockBuf, sizeof(LockBuf)) <= 0)
      {
         close(fd);
         return 0;
      }
      close(fd);
      
      if (sscanf(LockBuf, "%d", &procID) != 1)
      {
         return 0;
      }

      if (-1 != kill(procID, 0) || errno != ESRCH )
         return 0;

      syslog(LOG_WARNING,"Removing stale lock file.");
      unlink( LockFileName );

      // Yet another retry
      fd = open( LockFileName, O_WRONLY | O_CREAT | O_EXCL, 
                 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

      // Oh, I give up
      if (fd == -1) return 0;
      
   }

   sprintf( LockBuf, "%d", getpid());
   write(fd, LockBuf, strlen(LockBuf)+1);
   close(fd);
   PortLocked = 1;
   return 1;
}

// Checks for existance of the lock file
// returns:
//  1 - No lock file
//  0 - device is locked by another process
int Locks::CheckLockFile()
{
   int  fd;

   if (PortLocked) return 1;

   // If you use NFS, see man open for different implementation,
   // I'm toooooo lazy to do it the RIGHT way. Sorry.
   fd = open( LockFileName, O_RDONLY );
   if (fd == -1)
   {
      return 1; // No lock file...
   }

   close(fd);
   return 0;
}

// The name sez it all. 
void Locks::RemoveLockFile()
{
   FILE* fp;
   int pid;
   syslog(LOG_DEBUG,"Removing lock file name: %s",LockFileName);
   fp = fopen(LockFileName, "r");
   if (fp)
   {
      fscanf(fp, "%d", &pid);
      fclose(fp);
      if (pid == getpid())
         unlink( LockFileName );
      else
         syslog(LOG_ERR,
            "The lock file belongs to another process. Could not remove");
   }
   PortLocked = 0;
};