1 /****************************************************************************
2 * Copyright (C) 2006-2010 by Jason Ansel, Kapil Arya, and Gene Cooperman *
3 * jansel@csail.mit.edu, kapil@ccs.neu.edu, gene@ccs.neu.edu *
4 * *
5 * This file is part of the dmtcp/src module of DMTCP (DMTCP:dmtcp/src). *
6 * *
7 * DMTCP:dmtcp/src is free software: you can redistribute it and/or *
8 * modify it under the terms of the GNU Lesser General Public License as *
9 * published by the Free Software Foundation, either version 3 of the *
10 * License, or (at your option) any later version. *
11 * *
12 * DMTCP:dmtcp/src is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU Lesser General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with DMTCP:dmtcp/src. If not, see *
19 * <http://www.gnu.org/licenses/>. *
20 ****************************************************************************/
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <string>
25 #include <sstream>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <sys/syscall.h>
29 #include "constants.h"
30 #include "util.h"
31 #include "../jalib/jassert.h"
32
33 void dmtcp::Util::lockFile(int fd)
34 {
35 struct flock fl;
36
37 fl.l_type = F_WRLCK; // F_RDLCK, F_WRLCK, F_UNLCK
38 fl.l_whence = SEEK_SET; // SEEK_SET, SEEK_CUR, SEEK_END
39 fl.l_start = 0; // Offset from l_whence
40 fl.l_len = 0; // length, 0 = to EOF
41 //fl.l_pid = _real_getpid(); // our PID
42
43 int result = -1;
44 errno = 0;
45 while (result == -1 || errno == EINTR)
46 result = fcntl(fd, F_SETLKW, &fl); /* F_GETLK, F_SETLK, F_SETLKW */
47
48 JASSERT (result != -1) (JASSERT_ERRNO)
49 .Text("Unable to lock the PID MAP file");
50 }
51
52 void dmtcp::Util::unlockFile(int fd)
53 {
54 struct flock fl;
55 int result;
56 fl.l_type = F_UNLCK; // tell it to unlock the region
57 fl.l_whence = SEEK_SET; // SEEK_SET, SEEK_CUR, SEEK_END
58 fl.l_start = 0; // Offset from l_whence
59 fl.l_len = 0; // length, 0 = to EOF
60
61 result = fcntl(fd, F_SETLK, &fl); /* set the region to unlocked */
62
63 JASSERT (result != -1 || errno == ENOLCK) (JASSERT_ERRNO)
64 .Text("Unlock Failed");
65 }
66
67 bool dmtcp::Util::strStartsWith(const char *str, const char *pattern)
68 {
69 int len1 = strlen(str);
70 int len2 = strlen(pattern);
71 if (len1 >= len2) {
72 return strncmp(str, pattern, len2) == 0;
73 }
74 return false;
75 }
76
77 bool dmtcp::Util::strEndsWith(const char *str, const char *pattern)
78 {
79 int len1 = strlen(str);
80 int len2 = strlen(pattern);
81 if (len1 >= len2) {
82 size_t idx = len1 - len2;
83 return strncmp(str+idx, pattern, len2) == 0;
84 }
85 return false;
86 }
87
88 bool dmtcp::Util::strStartsWith(const dmtcp::string& str, const char *pattern)
89 {
90 if (str.length() >= strlen(pattern)) {
91 return str.compare(0, strlen(pattern), pattern) == 0;
92 }
93 return false;
94 }
95
96 bool dmtcp::Util::strEndsWith(const dmtcp::string& str, const char *pattern)
97 {
98 if (str.length() >= strlen(pattern)) {
99 size_t idx = str.length() - strlen(pattern);
100 return str.compare(idx, strlen(pattern), pattern) == 0;
101 }
102 return false;
103 }
104
105 // Fails or does entire write (returns count)
106 ssize_t dmtcp::Util::writeAll(int fd, const void *buf, size_t count)
107 {
108 const char *ptr = (const char *) buf;
109 ssize_t offs = 0;
110
111 do {
112 ssize_t rc = write (fd, ptr + offs, count - offs);
113 if (rc == -1) {
114 if (errno == EINTR || errno == EAGAIN)
115 continue;
116 else
117 return rc;
118 }
119 else if (rc == 0)
120 break;
121 else // else rc > 0
122 offs += rc;
123 } while (offs < count);
124 JASSERT (offs == count) (offs) (count);
125 return count;
126 }
127
128 // Fails, succeeds, or partial read due to EOF (returns num read)
129 // return value:
130 // -1: unrecoverable error
131 // <n>: number of bytes read
132 ssize_t dmtcp::Util::readAll(int fd, void *buf, size_t count)
133 {
134 size_t rc;
135 char *ptr = (char *) buf;
136 int num_read = 0;
|
At conditional (1): "num_read < count": Taking true branch.
|
137 for (num_read = 0; num_read < count;) {
|
Event neg_sink_parm_call: |
Passing "fd" to "read", which cannot accept a negative. |
138 rc = read (fd, ptr + num_read, count - num_read);
139 if (rc == -1) {
140 if (errno == EINTR || errno == EAGAIN)
141 continue;
142 else
143 return -1;
144 }
145 else if (rc == 0)
146 break;
147 else // else rc > 0
148 num_read += rc;
149 }
150 return num_read;
151 }