Mercurial > hg
annotate contrib/chg/util.c @ 35237:8df8ce2cc5dd
remotenames: add functionality to store remotenames under .hg/hgremotenames/
This patch moves the functionality from remotenames extension to store
remotenames to core.
Storage format used by remotenames extension:
A single file `.hg/remotenames` with an entry in each line where each line is of
format:
`node nametype remotepath/name`
where nametype is either 'bookmarks' or 'branches'.
This was not the best way to store data, so while moving to core the storage
format was changed but yet not the final format. The storage format used by core
after this patch will be:
* A file for each type of name i.e. bookmarks and branches in .hg/remotenames/
directory
* A version number on the top of the file. The version for current format is 0.
* An entry in each line where each line is of the format
`node\0remotepath\0name`
The logic to sync with existing remotenames file and saving journals and other
related things will be moved to core in next patches incrementally.
Thanks to Ryan, Augie and Durham for suggestions on storage format.
Previously reviewed as D939.
Differential Revision: https://phab.mercurial-scm.org/D1548
author | Pulkit Goyal <7895pulkit@gmail.com> |
---|---|
date | Thu, 05 Oct 2017 00:44:38 +0530 |
parents | b94db1780365 |
children | 9724f54923ec |
rev | line source |
---|---|
28060 | 1 /* |
2 * Utility functions | |
3 * | |
4 * Copyright (c) 2011 Yuya Nishihara <yuya@tcha.org> | |
5 * | |
6 * This software may be used and distributed according to the terms of the | |
7 * GNU General Public License version 2 or any later version. | |
8 */ | |
9 | |
28788
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
10 #include <errno.h> |
28855
f5764e177bbe
chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents:
28854
diff
changeset
|
11 #include <fcntl.h> |
28060 | 12 #include <signal.h> |
13 #include <stdarg.h> | |
14 #include <stdio.h> | |
15 #include <stdlib.h> | |
28084
3fc45956c978
chg: initialize sigaction fields more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
28060
diff
changeset
|
16 #include <string.h> |
34309
b94db1780365
chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents:
28855
diff
changeset
|
17 #include <sys/time.h> |
28060 | 18 #include <sys/types.h> |
19 #include <sys/wait.h> | |
20 #include <unistd.h> | |
21 | |
22 #include "util.h" | |
23 | |
28787
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
24 static int colorenabled = 0; |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
25 |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
26 static inline void fsetcolor(FILE *fp, const char *code) |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
27 { |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
28 if (!colorenabled) |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
29 return; |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
30 fprintf(fp, "\033[%sm", code); |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
31 } |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
32 |
28788
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
33 static void vabortmsgerrno(int no, const char *fmt, va_list args) |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
34 { |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
35 fsetcolor(stderr, "1;31"); |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
36 fputs("chg: abort: ", stderr); |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
37 vfprintf(stderr, fmt, args); |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
38 if (no != 0) |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
39 fprintf(stderr, " (errno = %d, %s)", no, strerror(no)); |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
40 fsetcolor(stderr, ""); |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
41 fputc('\n', stderr); |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
42 exit(255); |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
43 } |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
44 |
28060 | 45 void abortmsg(const char *fmt, ...) |
46 { | |
47 va_list args; | |
48 va_start(args, fmt); | |
28788
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
49 vabortmsgerrno(0, fmt, args); |
28060 | 50 va_end(args); |
28788
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
51 } |
28060 | 52 |
28788
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
53 void abortmsgerrno(const char *fmt, ...) |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
54 { |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
55 int no = errno; |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
56 va_list args; |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
57 va_start(args, fmt); |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
58 vabortmsgerrno(no, fmt, args); |
57a78a64de44
chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
59 va_end(args); |
28060 | 60 } |
61 | |
62 static int debugmsgenabled = 0; | |
34309
b94db1780365
chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents:
28855
diff
changeset
|
63 static double debugstart = 0; |
b94db1780365
chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents:
28855
diff
changeset
|
64 |
b94db1780365
chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents:
28855
diff
changeset
|
65 static double now() { |
b94db1780365
chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents:
28855
diff
changeset
|
66 struct timeval t; |
b94db1780365
chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents:
28855
diff
changeset
|
67 gettimeofday(&t, NULL); |
b94db1780365
chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents:
28855
diff
changeset
|
68 return t.tv_usec / 1e6 + t.tv_sec; |
b94db1780365
chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents:
28855
diff
changeset
|
69 } |
28060 | 70 |
28787
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
71 void enablecolor(void) |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
72 { |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
73 colorenabled = 1; |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
74 } |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
75 |
28060 | 76 void enabledebugmsg(void) |
77 { | |
78 debugmsgenabled = 1; | |
34309
b94db1780365
chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents:
28855
diff
changeset
|
79 debugstart = now(); |
28060 | 80 } |
81 | |
82 void debugmsg(const char *fmt, ...) | |
83 { | |
84 if (!debugmsgenabled) | |
85 return; | |
86 | |
87 va_list args; | |
88 va_start(args, fmt); | |
28787
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
89 fsetcolor(stderr, "1;30"); |
34309
b94db1780365
chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents:
28855
diff
changeset
|
90 fprintf(stderr, "chg: debug: %4.6f ", now() - debugstart); |
28060 | 91 vfprintf(stderr, fmt, args); |
28787
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
92 fsetcolor(stderr, ""); |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28165
diff
changeset
|
93 fputc('\n', stderr); |
28060 | 94 va_end(args); |
95 } | |
96 | |
28854
ddef14468952
chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents:
28788
diff
changeset
|
97 void fchdirx(int dirfd) |
ddef14468952
chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents:
28788
diff
changeset
|
98 { |
ddef14468952
chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents:
28788
diff
changeset
|
99 int r = fchdir(dirfd); |
ddef14468952
chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents:
28788
diff
changeset
|
100 if (r == -1) |
ddef14468952
chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents:
28788
diff
changeset
|
101 abortmsgerrno("failed to fchdir"); |
ddef14468952
chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents:
28788
diff
changeset
|
102 } |
ddef14468952
chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents:
28788
diff
changeset
|
103 |
28855
f5764e177bbe
chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents:
28854
diff
changeset
|
104 void fsetcloexec(int fd) |
f5764e177bbe
chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents:
28854
diff
changeset
|
105 { |
f5764e177bbe
chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents:
28854
diff
changeset
|
106 int flags = fcntl(fd, F_GETFD); |
f5764e177bbe
chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents:
28854
diff
changeset
|
107 if (flags < 0) |
f5764e177bbe
chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents:
28854
diff
changeset
|
108 abortmsgerrno("cannot get flags of fd %d", fd); |
f5764e177bbe
chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents:
28854
diff
changeset
|
109 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) |
f5764e177bbe
chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents:
28854
diff
changeset
|
110 abortmsgerrno("cannot set flags of fd %d", fd); |
f5764e177bbe
chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents:
28854
diff
changeset
|
111 } |
f5764e177bbe
chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents:
28854
diff
changeset
|
112 |
28165
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
113 void *mallocx(size_t size) |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
114 { |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
115 void *result = malloc(size); |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
116 if (!result) |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
117 abortmsg("failed to malloc"); |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
118 return result; |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
119 } |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
120 |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
121 void *reallocx(void *ptr, size_t size) |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
122 { |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
123 void *result = realloc(ptr, size); |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
124 if (!result) |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
125 abortmsg("failed to realloc"); |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
126 return result; |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
127 } |
c6705c6303dd
chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents:
28084
diff
changeset
|
128 |
28060 | 129 /* |
130 * Execute a shell command in mostly the same manner as system(), with the | |
131 * give environment variables, after chdir to the given cwd. Returns a status | |
132 * code compatible with the Python subprocess module. | |
133 */ | |
134 int runshellcmd(const char *cmd, const char *envp[], const char *cwd) | |
135 { | |
136 enum { F_SIGINT = 1, F_SIGQUIT = 2, F_SIGMASK = 4, F_WAITPID = 8 }; | |
137 unsigned int doneflags = 0; | |
138 int status = 0; | |
139 struct sigaction newsa, oldsaint, oldsaquit; | |
140 sigset_t oldmask; | |
141 | |
142 /* block or mask signals just as system() does */ | |
28084
3fc45956c978
chg: initialize sigaction fields more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
28060
diff
changeset
|
143 memset(&newsa, 0, sizeof(newsa)); |
28060 | 144 newsa.sa_handler = SIG_IGN; |
145 newsa.sa_flags = 0; | |
146 if (sigemptyset(&newsa.sa_mask) < 0) | |
147 goto done; | |
148 if (sigaction(SIGINT, &newsa, &oldsaint) < 0) | |
149 goto done; | |
150 doneflags |= F_SIGINT; | |
151 if (sigaction(SIGQUIT, &newsa, &oldsaquit) < 0) | |
152 goto done; | |
153 doneflags |= F_SIGQUIT; | |
154 | |
155 if (sigaddset(&newsa.sa_mask, SIGCHLD) < 0) | |
156 goto done; | |
157 if (sigprocmask(SIG_BLOCK, &newsa.sa_mask, &oldmask) < 0) | |
158 goto done; | |
159 doneflags |= F_SIGMASK; | |
160 | |
161 pid_t pid = fork(); | |
162 if (pid < 0) | |
163 goto done; | |
164 if (pid == 0) { | |
165 sigaction(SIGINT, &oldsaint, NULL); | |
166 sigaction(SIGQUIT, &oldsaquit, NULL); | |
167 sigprocmask(SIG_SETMASK, &oldmask, NULL); | |
168 if (cwd && chdir(cwd) < 0) | |
169 _exit(127); | |
170 const char *argv[] = {"sh", "-c", cmd, NULL}; | |
171 if (envp) { | |
172 execve("/bin/sh", (char **)argv, (char **)envp); | |
173 } else { | |
174 execv("/bin/sh", (char **)argv); | |
175 } | |
176 _exit(127); | |
177 } else { | |
178 if (waitpid(pid, &status, 0) < 0) | |
179 goto done; | |
180 doneflags |= F_WAITPID; | |
181 } | |
182 | |
183 done: | |
184 if (doneflags & F_SIGINT) | |
185 sigaction(SIGINT, &oldsaint, NULL); | |
186 if (doneflags & F_SIGQUIT) | |
187 sigaction(SIGQUIT, &oldsaquit, NULL); | |
188 if (doneflags & F_SIGMASK) | |
189 sigprocmask(SIG_SETMASK, &oldmask, NULL); | |
190 | |
191 /* no way to report other errors, use 127 (= shell termination) */ | |
192 if (!(doneflags & F_WAITPID)) | |
193 return 127; | |
194 if (WIFEXITED(status)) | |
195 return WEXITSTATUS(status); | |
196 if (WIFSIGNALED(status)) | |
197 return -WTERMSIG(status); | |
198 return 127; | |
199 } |