mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-27 00:57:19 +02:00
Portability: Use fcntl instead of flock
- POSIX file locking mechanism, eliminating platform-specific code.
This commit is contained in:
parent
71fef9f22f
commit
c346cf9395
6 changed files with 25 additions and 76 deletions
|
@ -7,6 +7,7 @@
|
|||
- TW-1605 Japanese translation for Taskwarrior (thanks to Oota Toshiya).
|
||||
- TW-1606 scheduled.any filter (thanks to Peter Rochen).
|
||||
- The 'obfuscate' setting, if set to '1' will replace all text with 'xxx'.
|
||||
- POSIX file locking mechanism, eliminating platform-specific code.
|
||||
|
||||
------ current release ---------------------------
|
||||
|
||||
|
|
48
src/File.cpp
48
src/File.cpp
|
@ -28,14 +28,10 @@
|
|||
#include <fstream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef SOLARIS
|
||||
#include <fcntl.h> // for flock() replacement
|
||||
#include <string.h> // for memset()
|
||||
#else
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <File.h>
|
||||
#include <text.h>
|
||||
#include <util.h>
|
||||
|
@ -151,6 +147,9 @@ void File::close ()
|
|||
{
|
||||
if (_fh)
|
||||
{
|
||||
if (_locked)
|
||||
unlock ();
|
||||
|
||||
fclose (_fh);
|
||||
_fh = NULL;
|
||||
_h = -1;
|
||||
|
@ -161,38 +160,31 @@ void File::close ()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool File::lock ()
|
||||
{
|
||||
_locked = false;
|
||||
if (_fh && _h != -1)
|
||||
{
|
||||
// Try three times before failing.
|
||||
int retry = 0;
|
||||
while (flock (_h, LOCK_NB | LOCK_EX) && ++retry <= 3)
|
||||
;
|
||||
|
||||
if (retry <= 3)
|
||||
{
|
||||
// l_type l_whence l_start l_len l_pid
|
||||
struct flock fl = {F_WRLCK, SEEK_SET, 0, 0, 0 };
|
||||
fl.l_pid = getpid ();
|
||||
if (fcntl (_h, F_SETLKW, &fl) == 0)
|
||||
_locked = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_locked = false;
|
||||
return false;
|
||||
return _locked;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool File::waitForLock ()
|
||||
void File::unlock ()
|
||||
{
|
||||
if (_locked)
|
||||
return true;
|
||||
{
|
||||
// l_type l_whence l_start l_len l_pid
|
||||
struct flock fl = {F_UNLCK, SEEK_SET, 0, 0, 0 };
|
||||
fl.l_pid = getpid ();
|
||||
|
||||
if (_fh && _h != -1)
|
||||
if (flock (_h, LOCK_EX) == 0)
|
||||
{
|
||||
_locked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
fcntl (_h, F_SETLK, &fl);
|
||||
_locked = false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
void close ();
|
||||
|
||||
bool lock ();
|
||||
bool waitForLock ();
|
||||
void unlock ();
|
||||
|
||||
void read (std::string&);
|
||||
void read (std::vector <std::string>&);
|
||||
|
|
|
@ -226,7 +226,7 @@ void TF2::commit ()
|
|||
if (_file.open ())
|
||||
{
|
||||
if (context.config.getBoolean ("locking"))
|
||||
_file.waitForLock ();
|
||||
_file.lock ();
|
||||
|
||||
// Write out all the added tasks.
|
||||
std::vector <Task>::iterator task;
|
||||
|
@ -258,7 +258,7 @@ void TF2::commit ()
|
|||
if (_file.open ())
|
||||
{
|
||||
if (context.config.getBoolean ("locking"))
|
||||
_file.waitForLock ();
|
||||
_file.lock ();
|
||||
|
||||
// Truncate the file and rewrite.
|
||||
_file.truncate ();
|
||||
|
@ -358,7 +358,7 @@ void TF2::load_lines ()
|
|||
if (_file.open ())
|
||||
{
|
||||
if (context.config.getBoolean ("locking"))
|
||||
_file.waitForLock ();
|
||||
_file.lock ();
|
||||
|
||||
_file.read (_lines);
|
||||
_file.close ();
|
||||
|
|
35
src/util.cpp
35
src/util.cpp
|
@ -42,7 +42,6 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -228,40 +227,6 @@ const std::string uuid ()
|
|||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// On Solaris no flock function exists.
|
||||
#ifdef SOLARIS
|
||||
int flock (int fd, int operation)
|
||||
{
|
||||
struct flock fl;
|
||||
|
||||
switch (operation & ~LOCK_NB)
|
||||
{
|
||||
case LOCK_SH:
|
||||
fl.l_type = F_RDLCK;
|
||||
break;
|
||||
|
||||
case LOCK_EX:
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
|
||||
case LOCK_UN:
|
||||
fl.l_type = F_UNLCK;
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fl.l_whence = 0;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 0;
|
||||
|
||||
return fcntl (fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &fl);
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Run a binary with args, capturing output.
|
||||
int execute (
|
||||
|
|
|
@ -52,15 +52,6 @@ const std::string uuid ();
|
|||
|
||||
int execute (const std::string&, const std::vector <std::string>&, const std::string&, std::string&);
|
||||
|
||||
#ifdef SOLARIS
|
||||
#define LOCK_SH 1
|
||||
#define LOCK_EX 2
|
||||
#define LOCK_NB 4
|
||||
#define LOCK_UN 8
|
||||
|
||||
int flock (int, int);
|
||||
#endif
|
||||
|
||||
const std::string indentProject (
|
||||
const std::string&,
|
||||
const std::string& whitespace = " ",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue