Show More
@@ -200,6 +200,50 b' def addremove(repo, pats=[], opts={}, wl' | |||||
200 | if not dry_run: |
|
200 | if not dry_run: | |
201 | repo.copy(old, new, wlock=wlock) |
|
201 | repo.copy(old, new, wlock=wlock) | |
202 |
|
202 | |||
|
203 | def service(opts, parentfn=None, initfn=None, runfn=None): | |||
|
204 | '''Run a command as a service.''' | |||
|
205 | ||||
|
206 | if opts['daemon'] and not opts['daemon_pipefds']: | |||
|
207 | rfd, wfd = os.pipe() | |||
|
208 | args = sys.argv[:] | |||
|
209 | args.append('--daemon-pipefds=%d,%d' % (rfd, wfd)) | |||
|
210 | pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0), | |||
|
211 | args[0], args) | |||
|
212 | os.close(wfd) | |||
|
213 | os.read(rfd, 1) | |||
|
214 | if parentfn: | |||
|
215 | return parentfn(pid) | |||
|
216 | else: | |||
|
217 | os._exit(0) | |||
|
218 | ||||
|
219 | if initfn: | |||
|
220 | initfn() | |||
|
221 | ||||
|
222 | if opts['pid_file']: | |||
|
223 | fp = open(opts['pid_file'], 'w') | |||
|
224 | fp.write(str(os.getpid()) + '\n') | |||
|
225 | fp.close() | |||
|
226 | ||||
|
227 | if opts['daemon_pipefds']: | |||
|
228 | rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')] | |||
|
229 | os.close(rfd) | |||
|
230 | try: | |||
|
231 | os.setsid() | |||
|
232 | except AttributeError: | |||
|
233 | pass | |||
|
234 | os.write(wfd, 'y') | |||
|
235 | os.close(wfd) | |||
|
236 | sys.stdout.flush() | |||
|
237 | sys.stderr.flush() | |||
|
238 | fd = os.open(util.nulldev, os.O_RDWR) | |||
|
239 | if fd != 0: os.dup2(fd, 0) | |||
|
240 | if fd != 1: os.dup2(fd, 1) | |||
|
241 | if fd != 2: os.dup2(fd, 2) | |||
|
242 | if fd not in (0, 1, 2): os.close(fd) | |||
|
243 | ||||
|
244 | if runfn: | |||
|
245 | return runfn() | |||
|
246 | ||||
203 | class changeset_printer(object): |
|
247 | class changeset_printer(object): | |
204 | '''show changeset information when templating not requested.''' |
|
248 | '''show changeset information when templating not requested.''' | |
205 |
|
249 |
@@ -2375,44 +2375,27 b' def serve(ui, repo, **opts):' | |||||
2375 | raise hg.RepoError(_("There is no Mercurial repository here" |
|
2375 | raise hg.RepoError(_("There is no Mercurial repository here" | |
2376 | " (.hg not found)")) |
|
2376 | " (.hg not found)")) | |
2377 |
|
2377 | |||
2378 | if opts['daemon'] and not opts['daemon_pipefds']: |
|
2378 | class service: | |
2379 | rfd, wfd = os.pipe() |
|
2379 | def init(self): | |
2380 | args = sys.argv[:] |
|
2380 | try: | |
2381 | args.append('--daemon-pipefds=%d,%d' % (rfd, wfd)) |
|
2381 | self.httpd = hgweb.server.create_server(parentui, repo) | |
2382 | pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0), |
|
2382 | except socket.error, inst: | |
2383 | args[0], args) |
|
2383 | raise util.Abort(_('cannot start server: ') + inst.args[1]) | |
2384 | os.close(wfd) |
|
2384 | ||
2385 | os.read(rfd, 1) |
|
2385 | if not ui.verbose: return | |
2386 | os._exit(0) |
|
2386 | ||
2387 |
|
2387 | if httpd.port != 80: | ||
2388 | httpd = hgweb.server.create_server(parentui, repo) |
|
2388 | ui.status(_('listening at http://%s:%d/\n') % | |
2389 |
|
2389 | (httpd.addr, httpd.port)) | ||
2390 | if ui.verbose: |
|
2390 | else: | |
2391 | if httpd.port != 80: |
|
2391 | ui.status(_('listening at http://%s/\n') % httpd.addr) | |
2392 | ui.status(_('listening at http://%s:%d/\n') % |
|
2392 | ||
2393 | (httpd.addr, httpd.port)) |
|
2393 | def run(self): | |
2394 | else: |
|
2394 | self.httpd.serve_forever() | |
2395 | ui.status(_('listening at http://%s/\n') % httpd.addr) |
|
2395 | ||
2396 |
|
2396 | service = service() | ||
2397 | if opts['pid_file']: |
|
2397 | ||
2398 | fp = open(opts['pid_file'], 'w') |
|
2398 | cmdutil.service(opts, initfn=service.init, runfn=service.run) | |
2399 | fp.write(str(os.getpid()) + '\n') |
|
|||
2400 | fp.close() |
|
|||
2401 |
|
||||
2402 | if opts['daemon_pipefds']: |
|
|||
2403 | rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')] |
|
|||
2404 | os.close(rfd) |
|
|||
2405 | os.write(wfd, 'y') |
|
|||
2406 | os.close(wfd) |
|
|||
2407 | sys.stdout.flush() |
|
|||
2408 | sys.stderr.flush() |
|
|||
2409 | fd = os.open(util.nulldev, os.O_RDWR) |
|
|||
2410 | if fd != 0: os.dup2(fd, 0) |
|
|||
2411 | if fd != 1: os.dup2(fd, 1) |
|
|||
2412 | if fd != 2: os.dup2(fd, 2) |
|
|||
2413 | if fd not in (0, 1, 2): os.close(fd) |
|
|||
2414 |
|
||||
2415 | httpd.serve_forever() |
|
|||
2416 |
|
2399 | |||
2417 | def status(ui, repo, *pats, **opts): |
|
2400 | def status(ui, repo, *pats, **opts): | |
2418 | """show changed files in the working directory |
|
2401 | """show changed files in the working directory |
@@ -225,7 +225,7 b' static struct flist *decode(char *bin, i' | |||||
225 | { |
|
225 | { | |
226 | struct flist *l; |
|
226 | struct flist *l; | |
227 | struct frag *lt; |
|
227 | struct frag *lt; | |
228 | char *end = bin + len; |
|
228 | char *data = bin + 12, *end = bin + len; | |
229 | char decode[12]; /* for dealing with alignment issues */ |
|
229 | char decode[12]; /* for dealing with alignment issues */ | |
230 |
|
230 | |||
231 | /* assume worst case size, we won't have many of these lists */ |
|
231 | /* assume worst case size, we won't have many of these lists */ | |
@@ -235,13 +235,18 b' static struct flist *decode(char *bin, i' | |||||
235 |
|
235 | |||
236 | lt = l->tail; |
|
236 | lt = l->tail; | |
237 |
|
237 | |||
238 |
while ( |
|
238 | while (data <= end) { | |
239 | memcpy(decode, bin, 12); |
|
239 | memcpy(decode, bin, 12); | |
240 | lt->start = ntohl(*(uint32_t *)decode); |
|
240 | lt->start = ntohl(*(uint32_t *)decode); | |
241 | lt->end = ntohl(*(uint32_t *)(decode + 4)); |
|
241 | lt->end = ntohl(*(uint32_t *)(decode + 4)); | |
242 | lt->len = ntohl(*(uint32_t *)(decode + 8)); |
|
242 | lt->len = ntohl(*(uint32_t *)(decode + 8)); | |
243 | lt->data = bin + 12; |
|
243 | if (lt->start > lt->end) | |
244 | bin += 12 + lt->len; |
|
244 | break; /* sanity check */ | |
|
245 | bin = data + lt->len; | |||
|
246 | if (bin < data) | |||
|
247 | break; /* big data + big (bogus) len can wrap around */ | |||
|
248 | lt->data = data; | |||
|
249 | data = bin + 12; | |||
245 | lt++; |
|
250 | lt++; | |
246 | } |
|
251 | } | |
247 |
|
252 | |||
@@ -371,20 +376,26 b' patchedsize(PyObject *self, PyObject *ar' | |||||
371 | { |
|
376 | { | |
372 | long orig, start, end, len, outlen = 0, last = 0; |
|
377 | long orig, start, end, len, outlen = 0, last = 0; | |
373 | int patchlen; |
|
378 | int patchlen; | |
374 | char *bin, *binend; |
|
379 | char *bin, *binend, *data; | |
375 | char decode[12]; /* for dealing with alignment issues */ |
|
380 | char decode[12]; /* for dealing with alignment issues */ | |
376 |
|
381 | |||
377 | if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen)) |
|
382 | if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen)) | |
378 | return NULL; |
|
383 | return NULL; | |
379 |
|
384 | |||
380 | binend = bin + patchlen; |
|
385 | binend = bin + patchlen; | |
|
386 | data = bin + 12; | |||
381 |
|
387 | |||
382 |
while ( |
|
388 | while (data <= binend) { | |
383 | memcpy(decode, bin, 12); |
|
389 | memcpy(decode, bin, 12); | |
384 | start = ntohl(*(uint32_t *)decode); |
|
390 | start = ntohl(*(uint32_t *)decode); | |
385 | end = ntohl(*(uint32_t *)(decode + 4)); |
|
391 | end = ntohl(*(uint32_t *)(decode + 4)); | |
386 | len = ntohl(*(uint32_t *)(decode + 8)); |
|
392 | len = ntohl(*(uint32_t *)(decode + 8)); | |
387 | bin += 12 + len; |
|
393 | if (start > end) | |
|
394 | break; /* sanity check */ | |||
|
395 | bin = data + len; | |||
|
396 | if (bin < data) | |||
|
397 | break; /* big data + big (bogus) len can wrap around */ | |||
|
398 | data = bin + 12; | |||
388 | outlen += start - last; |
|
399 | outlen += start - last; | |
389 | last = end; |
|
400 | last = end; | |
390 | outlen += len; |
|
401 | outlen += len; |
@@ -1161,11 +1161,19 b' def opener(base, audit=True):' | |||||
1161 | class atomicfile(atomictempfile): |
|
1161 | class atomicfile(atomictempfile): | |
1162 | """the file will only be copied on close""" |
|
1162 | """the file will only be copied on close""" | |
1163 | def __init__(self, name, mode): |
|
1163 | def __init__(self, name, mode): | |
|
1164 | self._err = False | |||
1164 | atomictempfile.__init__(self, name, mode) |
|
1165 | atomictempfile.__init__(self, name, mode) | |
|
1166 | def write(self, s): | |||
|
1167 | try: | |||
|
1168 | atomictempfile.write(self, s) | |||
|
1169 | except: | |||
|
1170 | self._err = True | |||
|
1171 | raise | |||
1165 | def close(self): |
|
1172 | def close(self): | |
1166 | self.rename() |
|
1173 | self.rename() | |
1167 | def __del__(self): |
|
1174 | def __del__(self): | |
1168 |
self. |
|
1175 | if not self._err: | |
|
1176 | self.rename() | |||
1169 |
|
1177 | |||
1170 | def o(path, mode="r", text=False, atomic=False, atomictemp=False): |
|
1178 | def o(path, mode="r", text=False, atomic=False, atomictemp=False): | |
1171 | if audit_p: |
|
1179 | if audit_p: |
General Comments 0
You need to be logged in to leave comments.
Login now