Trisurf Monte Carlo simulator
Samo Penic
2016-03-15 6e42ef0edaba59fd344e89ffd469202ff2bd39ac
commit | author | age
7f6076 1 /* vim: set ts=4 sts=4 sw=4 noet : */
d7639a 2 #include<stdio.h>
SP 3 #include<stdlib.h>
4 #include "general.h"
5 #include<stdarg.h>
6
1ab449 7 #include <sys/time.h>
SP 8 #include <unistd.h>
9 #include <time.h>
10
fbbc8e 11 #include <sys/stat.h>
SP 12 #include <fcntl.h>
13 #include <errno.h>
14 #include <string.h>
1ab449 15
a10dd5 16 ts_uint ts_fprintf(FILE *fd, char *fmt, ...){
d7639a 17 if(quiet) return TS_SUCCESS;
1ab449 18     va_list ap;
SP 19     va_start(ap,fmt);
20     char tmbuf[255];
21     struct timeval now;
22       gettimeofday(&now, 0);
23     strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", localtime(&now.tv_sec));
24 fprintf(fd, "[%s] ",tmbuf); 
a10dd5 25 vfprintf(fd, fmt, ap); /* Call vfprintf */
d7639a 26 va_end(ap); /* Cleanup the va_list */
SP 27 return TS_SUCCESS;
28 }
29
30 void err(char *text){
31     ts_fprintf(stderr,"Err: %s\n", text);
32 }
33
34 void fatal(char *text, ts_int errcode){
35     ts_fprintf(stderr,"Fatal: %s. TERMINATED!\n", text);
36     exit(errcode);
37 }
38
39
fbbc8e 40 /* Open/create the file named in 'pidFile', lock it, optionally set the
SP 41    close-on-exec flag for the file descriptor, write our PID into the file,
42    and (in case the caller is interested) return the file descriptor
43    referring to the locked file. The caller is responsible for deleting
44    'pidFile' file (just) before process termination. 'progName' should be the
45    name of the calling program (i.e., argv[0] or similar), and is used only for
46    diagnostic messages. If we can't open 'pidFile', or we encounter some other
47    error, then we print an appropriate diagnostic and terminate. */
48
49 /* 
50  This is filelock/create_pid_file.c (Listing 55-4, page 1143), an example program file from the book, The Linux Programming Interface.
51
52 The source code file is copyright 2010, Michael Kerrisk, and is licensed under the GNU Lesser General Public License, version 3. 
53 */
54
55 #define BUF_SIZE 100
56 int createPidFile(const char *progName, const char *pidFile, int flags)
57 {
58     int fd;
59     char buf[BUF_SIZE];
60
61     fd = open(pidFile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
62     if (fd == -1){
63         ts_fprintf(stderr,"Could not open PID file %s", pidFile);
6e42ef 64     fatal("Cannot continue (1)",1);
fbbc8e 65 }
SP 66     if (flags & CPF_CLOEXEC) {
67
68         /* Set the close-on-exec file descriptor flag */
69
70         /* Instead of the following steps, we could (on Linux) have opened the
71            file with O_CLOEXEC flag. However, not all systems support open()
72            O_CLOEXEC (which was standardized only in SUSv4), so instead we use
73            fcntl() to set the close-on-exec flag after opening the file */
74
75         flags = fcntl(fd, F_GETFD);                     /* Fetch flags */
76         if (flags == -1){
77             ts_fprintf(stderr,"Could not get flags for PID file %s", pidFile);
6e42ef 78     fatal("Cannot continue (2)",1);
fbbc8e 79 }
SP 80         flags |= FD_CLOEXEC;                            /* Turn on FD_CLOEXEC */
81
82         if (fcntl(fd, F_SETFD, flags) == -1)            /* Update flags */
83             ts_fprintf(stderr,"Could not set flags for PID file %s", pidFile);
6e42ef 84         fatal("Cannot continue (3)",1);
fbbc8e 85         
SP 86     }
87
88     if (lockRegion(fd, F_WRLCK, SEEK_SET, 0, 0) == -1) {
89         if (errno  == EAGAIN || errno == EACCES){
90             ts_fprintf(stderr,"PID file '%s' is locked; probably "
91                      "'%s' is already running", pidFile, progName);
6e42ef 92         fatal("Cannot continue (4)",1);
fbbc8e 93 }
SP 94         else{
95             ts_fprintf(stderr,"Unable to lock PID file '%s'", pidFile);
6e42ef 96     fatal("Cannot continue (5)",1);
fbbc8e 97 }
SP 98     }
99
100     if (ftruncate(fd, 0) == -1){
101         ts_fprintf(stderr,"Could not truncate PID file '%s'", pidFile);
6e42ef 102     fatal("Cannot continue (6)",1);
fbbc8e 103 }
SP 104
105     snprintf(buf, BUF_SIZE, "%ld\n", (long) getpid());
106     if (write(fd, buf, strlen(buf)) != strlen(buf)){
107
108         ts_fprintf(stderr,"Writing to PID file '%s'", pidFile);
6e42ef 109     fatal("Cannot continue (7)",1);
fbbc8e 110 }
SP 111     return fd;
112 }
113
114
115
116 /* Lock a file region (private; public interfaces below) */
117
118 static int
119 lockReg(int fd, int cmd, int type, int whence, int start, off_t len)
120 {
121     struct flock fl;
122
123     fl.l_type = type;
124     fl.l_whence = whence;
125     fl.l_start = start;
126     fl.l_len = len;
127
128     return fcntl(fd, cmd, &fl);
129 }
130
131
132 int                     /* Lock a file region using nonblocking F_SETLK */
133 lockRegion(int fd, int type, int whence, int start, int len)
134 {
135     return lockReg(fd, F_SETLK, type, whence, start, len);
136 }
137