#include #include #include #include #include #include #include #include int pidfilefd=-1; char *pidfile=NULL; /* Check if a pidfile is locked. Return 0 if not, or the pid if it is */ int pidfile_islocked(const char *pidfile) { struct flock fl; int fd,n; fl.l_type=F_WRLCK; fl.l_whence=SEEK_SET; fl.l_start=0; fl.l_len=0; fl.l_pid=0; fd=open(pidfile,O_WRONLY); if (fd==-1) return(0); n=fcntl(fd,F_GETLK, &fl); close(fd); if ((n==-1) || (fl.l_type==F_UNLCK)) return(0); return(fl.l_pid); } /* Do the pidfile locking. Return: 0: No lock existed. File was updated/created >0: File existed and it was locked - pid is returned */ int pidfile_dolock(const char *pfile) { struct flock fl; int fd,n; int ret=0; fl.l_type=F_WRLCK; fl.l_whence=SEEK_SET; fl.l_start=0; fl.l_len=0; fl.l_pid=getpid(); fd=open(pfile,O_RDWR); if (fd>=0) /* file exists */ { n=fcntl(fd, F_SETLK, &fl); if (n==0) /* wasn't locked */ { fl.l_type=F_UNLCK; fcntl(fd,F_SETLK,&fl); /* unlock it */ close(fd); pidfilefd=open(pfile,O_RDWR | O_TRUNC | O_SYNC); ret=0; } else /* locked */ { n=fcntl(fd, F_GETLK, &fl); if (n==-1) /* race condition ? */ { close(fd); pidfilefd=open(pfile, O_RDWR | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR); ret=0; } else { ret=fl.l_pid; } } } else { pidfilefd=open(pfile, O_RDWR | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR); ret=0; } if (ret==0) /* At this point, if ret==0, file is open with size 0 and ready for writting */ { char buf[30]; sprintf(buf,"%d\n",getpid()); write(pidfilefd,buf,strlen(buf)); /* Write the pid */ fl.l_pid=getpid(); fl.l_type=F_WRLCK; fl.l_start=0; fl.l_len=0; fl.l_whence=SEEK_SET; n=fcntl(pidfilefd, F_SETLK, &fl); if (pidfile!=NULL) free(pidfile); pidfile=strdup(pfile); } return(ret); } /* Remove the advisory lock and the pidfile */ void pidfile_dounlock() { int n; struct flock fl; fl.l_type=F_UNLCK; fl.l_whence=SEEK_SET; fl.l_start=0; fl.l_len=0; fl.l_pid=getpid(); if (pidfilefd==-1) return; n=fcntl(pidfilefd,F_SETLK,&fl); close(pidfilefd); unlink(pidfile); free(pidfile); pidfile=NULL; }