📄 lockfile.cpp
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by// the GNU General Public License. //// This exception applies only to the code released under the name GNU// Common C++. If you copy code from other releases into a copy of GNU// Common C++, as the General Public License permits, the exception does// not apply to the code that you add in this way. To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU Common C++, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include <cc++/config.h>#include <cc++/export.h>#include <cc++/thread.h>#include <cc++/process.h>#include <cc++/strchar.h>#include <sys/stat.h>#include <cstdlib>#include <cstdio>#include <cerrno>#ifdef CCXX_NAMESPACESnamespace ost {#endif#ifdef WIN32Lockfile::Lockfile(){ _mutex = INVALID_HANDLE_VALUE; _flagged = false;}Lockfile::Lockfile(const char *name){ _mutex = INVALID_HANDLE_VALUE; _flagged = false; lock(name);}bool Lockfile::lock(const char *name){ char mname[65]; char *ext = strrchr(name, '/'); if(ext) name = ++ext; unlock(); snprintf(mname, sizeof(mname) - 4, "_lock_%s", name); ext = strrchr(mname, '.'); if(ext && !stricmp(ext, ".lock")) { *ext = 0; ext = NULL; } if(!ext) addString(mname, sizeof(mname), ".lck"); _mutex = CreateMutex(NULL, FALSE, mname); if(WaitForSingleObject(_mutex, 200) == WAIT_OBJECT_0) _flagged = true; return _flagged;}void Lockfile::unlock(void){ if(_mutex == INVALID_HANDLE_VALUE) return; if(_flagged) ReleaseMutex(_mutex); CloseHandle(_mutex); _flagged = false; _mutex = INVALID_HANDLE_VALUE;}bool Lockfile::isLocked(void){ return _flagged;}#elseLockfile::Lockfile(){ _path = NULL;}Lockfile::Lockfile(const char *name){ _path = NULL; lock(name);}bool Lockfile::lock(const char *name){ struct stat ino; int fd, pid, status; const char *ext; char buffer[128]; unlock(); ext = strrchr(name, '/'); if(ext) ext = strrchr(ext, '.'); else ext = strrchr(name, '.'); if(strchr(name, '/')) { _path = new char[strlen(name) + 1]; strcpy(_path, name); } else if(ext && !stricmp(ext, ".pid")) { if(stat("/var/run", &ino)) snprintf(buffer, sizeof(buffer), "/tmp/.%s", name); else snprintf(buffer, sizeof(buffer), "/var/run/%s", name); _path = new char[strlen(buffer) + 1]; strcpy(_path, buffer); } else { if(!ext) ext = ".lock"; if(stat("/var/lock", &ino)) snprintf(buffer, sizeof(buffer), "/tmp/.%s%s", name, ext); else snprintf(buffer, sizeof(buffer), "/var/lock/%s%s", name, ext); _path = new char[strlen(buffer) + 1]; strcpy(_path, buffer); } for(;;) { fd = ::open(_path, O_WRONLY | O_CREAT | O_EXCL, 0660); if(fd > 0) { pid = getpid(); snprintf(buffer, sizeof(buffer), "%d\n", pid); ::write(fd, buffer, strlen(buffer)); ::close(fd); return true; } if(fd < 0 && errno != EEXIST) { delete[] _path; return false; } fd = ::open(_path, O_RDONLY); if(fd < 0) { if(errno == ENOENT) continue; delete[] _path; return false; } Thread::sleep(2000); status = ::read(fd, buffer, sizeof(buffer) - 1); if(status < 1) { ::close(fd); continue; } buffer[status] = 0; pid = atoi(buffer); if(pid) { if(pid == getpid()) { status = -1; errno = 0; } else status = kill(pid, 0); if(!status || (errno == EPERM)) { ::close(fd); delete[] _path; return false; } } ::close(fd); ::unlink(_path); }} void Lockfile::unlock(void){ if(_path) { remove(_path); delete[] _path; _path = NULL; }} bool Lockfile::isLocked(void){ if(_path) return true; return false;}#endif#ifdef CCXX_NAMESPACES}#endif/** EMACS ** * Local variables: * mode: c++ * c-basic-offset: 8 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -