LCOV - code coverage report
Current view: top level - src - lock.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 66 81 81.5 %
Date: 2017-08-31 Functions: 10 10 100.0 %

          Line data    Source code
       1             : #include "burp.h"
       2             : #include "alloc.h"
       3             : #include "lock.h"
       4             : #include "log.h"
       5             : 
       6          17 : struct lock *lock_alloc(void)
       7             : {
       8         423 :         return (struct lock *)calloc_w(1, sizeof(struct lock), __func__);
       9             : }
      10             : 
      11         424 : int lock_init(struct lock *lock, const char *path)
      12             : {
      13         424 :         free_w(&lock->path);
      14         424 :         if(!(lock->path=strdup_w(path, __func__)))
      15             :                 return -1;
      16         424 :         return 0;
      17             : }
      18             : 
      19         406 : struct lock *lock_alloc_and_init(const char *path)
      20             : {
      21             :         struct lock *lock;
      22         406 :         if(!(lock=lock_alloc()) || lock_init(lock, path))
      23           0 :                 lock_free(&lock);
      24         406 :         return lock;
      25             : }
      26             : 
      27             : static void lock_free_content(struct lock *lock)
      28             : {
      29         422 :         free_w(&lock->path);
      30             : }
      31             : 
      32         431 : void lock_free(struct lock **lock)
      33             : {
      34         862 :         if(!lock || !*lock) return;
      35         422 :         lock_free_content(*lock);
      36         422 :         free_v((void **)lock);
      37             : }
      38             : 
      39         101 : void lock_get_quick(struct lock *lock)
      40             : {
      41             : #if defined(HAVE_WIN32) || !defined(HAVE_LOCKF)
      42             :         // Would somebody please tell me how to get a lock on Windows?!
      43             :         lock->status=GET_LOCK_GOT;
      44             :         return;
      45             : #else
      46         101 :         char text[64]="";
      47             : 
      48         202 :         if((lock->fd=open(lock->path, O_WRONLY|O_CREAT, 0666))<0)
      49             :         {
      50           0 :                 logp("Could not open lock file %s: %s\n",
      51           0 :                         lock->path, strerror(errno));
      52           0 :                 goto error;
      53             :         }
      54         101 :         if(lockf(lock->fd, F_TLOCK, 0))
      55             :         {
      56           2 :                 if(errno==EACCES || errno==EAGAIN)
      57             :                         goto notgot;
      58           0 :                 logp("Could not get lock %s: %s\n",
      59             :                         lock->path, strerror(errno));
      60           0 :                 goto error; // Some other error.
      61             :         }
      62          99 :         snprintf(text, sizeof(text), "%d\n%s\n", (int)getpid(), progname());
      63          99 :         if(write(lock->fd, text, strlen(text))!=(ssize_t)strlen(text))
      64             :         {
      65           0 :                 logp("Could not write pid/progname to %s: %s\n",
      66           0 :                         lock->path, strerror(errno));
      67           0 :                 goto error;
      68             :         }
      69          99 :         lock->status=GET_LOCK_GOT;
      70          99 :         return;
      71             : error:
      72           0 :         lock->status=GET_LOCK_ERROR;
      73           0 :         return;
      74             : notgot:
      75           2 :         lock->status=GET_LOCK_NOT_GOT;
      76           2 :         return;
      77             : #endif
      78             : }
      79             : 
      80             : // Return 0 for lock got, 1 for lock not got, -1 for error.
      81          80 : void lock_get(struct lock *lock)
      82             : {
      83             : #if defined(HAVE_WIN32) || !defined(HAVE_LOCKF)
      84             :         // Would somebody please tell me how to get a lock on Windows?!
      85             :         lock->status=GET_LOCK_GOT;
      86             :         return;
      87             : #else
      88          80 :         char *cp=NULL;
      89          80 :         char *copy=NULL;
      90             : 
      91             :         // Try to make sure the lock directory exists.
      92          80 :         if(!(copy=strdup_w(lock->path, __func__)))
      93             :         {
      94           0 :                 lock->status=GET_LOCK_ERROR;
      95           0 :                 return;
      96             :         }
      97          80 :         if((cp=strrchr(copy, '/')))
      98             :         {
      99          80 :                 *cp='\0';
     100          80 :                 if(*copy) mkdir(copy, 0777);
     101             :         }
     102          80 :         free_w(&copy);
     103             : 
     104          80 :         lock_get_quick(lock);
     105             : 
     106             :         // Try to make sure the pid gets onto the disk.
     107          80 :         if(lock->status==GET_LOCK_GOT) fsync(lock->fd);
     108             :         return;
     109             : #endif
     110             : }
     111             : 
     112          10 : int lock_test(const char *path)
     113             : {
     114             : #if defined(HAVE_WIN32) || !defined(HAVE_LOCKF)
     115             :         // Would somebody please tell me how to test a lock on Windows?!
     116             :         return 0;
     117             : #else
     118          10 :         int r=0;
     119             :         int fdlock;
     120             : 
     121          10 :         if((fdlock=open(path, O_WRONLY, 0666))<0)
     122             :                 return 0; // file does not exist - could have got the lock
     123           2 :         errno=0;
     124           2 :         if((r=lockf(fdlock, F_TLOCK, 0)) && (errno==EAGAIN || errno==EACCES))
     125             :         {
     126             :                 // could not have got the lock
     127           1 :                 close(fdlock);
     128           1 :                 return -1;
     129             :         }
     130           1 :         close(fdlock);
     131             :         // could have got the lock
     132           1 :         return 0;
     133             : #endif
     134             : }
     135             : 
     136         117 : int lock_release(struct lock *lock)
     137             : {
     138         117 :         int ret=0;
     139         117 :         if(!lock || lock->status!=GET_LOCK_GOT) return 0;
     140          98 :         if(lock->path) unlink(lock->path);
     141          98 :         if(lock->fd>=0)
     142             :         {
     143          98 :                 if((ret=close(lock->fd)))
     144           0 :                         logp("Could not close %s: %s\n",
     145           0 :                                 lock->path, strerror(errno));
     146          98 :                 lock->fd=-1;
     147             :         }
     148          98 :         lock->status=GET_LOCK_NOT_GOT;
     149          98 :         return ret;
     150             : }
     151             : 
     152           3 : void lock_add_to_list(struct lock **locklist, struct lock *lock)
     153             : {
     154           3 :         if(*locklist) lock->next=*locklist;
     155           3 :         *locklist=lock;
     156           3 : }
     157             : 
     158           4 : void locks_release_and_free(struct lock **locklist)
     159             : {
     160             :         struct lock *l;
     161             :         struct lock *head;
     162           7 :         if(!locklist) return;
     163           1 :         head=*locklist;
     164           5 :         while(head)
     165             :         {
     166           3 :                 l=head;
     167           3 :                 head=head->next;
     168           3 :                 lock_release(l);
     169           3 :                 lock_free(&l);
     170             :         }
     171           1 :         *locklist=NULL;
     172             : }

Generated by: LCOV version 1.10