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

Generated by: LCOV version 1.10