Skip to content

Commit

Permalink
added file locking capability if --csv results are written to file
Browse files Browse the repository at this point in the history
  • Loading branch information
vbajpai authored and rewolff committed May 13, 2013
1 parent 9807ccd commit 562551b
Showing 1 changed file with 69 additions and 7 deletions.
76 changes: 69 additions & 7 deletions mtr.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
#include <errno.h>
#include <string.h>
#include <ctype.h>

#include <assert.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "mtr.h"
#include "mtr-curses.h"
Expand Down Expand Up @@ -174,6 +176,64 @@ read_from_file(const char* progname, const char *filename) {
if (in != stdin) fclose(in);
}

/*
* If the file stream is associated with a regular file, lock the file
* in order coordinate writes to a common file from multiple mtr
* instances. This is useful if, for example, multiple mtr instances
* try to append results to a common file.
*/

static void
lock(const char* progname, FILE *f) {
int fd;
struct stat buf;
static struct flock lock;

assert(f);

lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_END;
lock.l_len = 0;
lock.l_pid = getpid();

fd = fileno(f);
if ((fstat(fd, &buf) == 0) && S_ISREG(buf.st_mode)) {
if (fcntl(fd, F_SETLKW, &lock) == -1) {
fprintf(stderr, "%s: fcntl: %s (ignored)\n",
progname, strerror(errno));
}
}
}

/*
* If the file stream is associated with a regular file, unlock the
* file (which presumably has previously been locked).
*/

static void
unlock(const char* progname, FILE *f) {
int fd;
struct stat buf;
static struct flock lock;

assert(f);

lock.l_type = F_UNLCK;
lock.l_start = 0;
lock.l_whence = SEEK_END;
lock.l_len = 0;
lock.l_pid = getpid();

fd = fileno(f);
if ((fstat(fd, &buf) == 0) && S_ISREG(buf.st_mode)) {
if (fcntl(fd, F_SETLKW, &lock) == -1) {
fprintf(stderr, "%s: fcntl: %s (ignored)\n",
progname, strerror(errno));
}
}
}


void init_fld_options (void)
{
Expand Down Expand Up @@ -615,14 +675,16 @@ int main(int argc, char **argv)
}
}

display_open();
dns_open();
lock(argv[0], stdout);
display_open();
dns_open();

display_mode = 0;
display_loop();
display_mode = 0;
display_loop();

net_end_transit();
display_close(now);
net_end_transit();
display_close(now);
unlock(argv[0], stdout);

if ( DisplayMode != DisplayCSV ) break;
else names = names->next;
Expand Down

0 comments on commit 562551b

Please sign in to comment.