##// END OF EJS Templates
Merge with crew
Brendan Cully -
r4383:28054fc3 merge default
parent child Browse files
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 (bin < end) {
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 (bin < binend) {
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.rename()
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