##// END OF EJS Templates
cleanup: use clang-tidy to add missing {} around one-line statements...
Augie Fackler -
r41367:763b45bc default
parent child Browse files
Show More
@@ -84,8 +84,9 b' static void initcontext(context_t *ctx)'
84
84
85 static void enlargecontext(context_t *ctx, size_t newsize)
85 static void enlargecontext(context_t *ctx, size_t newsize)
86 {
86 {
87 if (newsize <= ctx->maxdatasize)
87 if (newsize <= ctx->maxdatasize) {
88 return;
88 return;
89 }
89
90
90 newsize = defaultdatasize *
91 newsize = defaultdatasize *
91 ((newsize + defaultdatasize - 1) / defaultdatasize);
92 ((newsize + defaultdatasize - 1) / defaultdatasize);
@@ -117,22 +118,25 b' static void readchannel(hgclient_t *hgc)'
117
118
118 uint32_t datasize_n;
119 uint32_t datasize_n;
119 rsize = recv(hgc->sockfd, &datasize_n, sizeof(datasize_n), 0);
120 rsize = recv(hgc->sockfd, &datasize_n, sizeof(datasize_n), 0);
120 if (rsize != sizeof(datasize_n))
121 if (rsize != sizeof(datasize_n)) {
121 abortmsg("failed to read data size");
122 abortmsg("failed to read data size");
123 }
122
124
123 /* datasize denotes the maximum size to write if input request */
125 /* datasize denotes the maximum size to write if input request */
124 hgc->ctx.datasize = ntohl(datasize_n);
126 hgc->ctx.datasize = ntohl(datasize_n);
125 enlargecontext(&hgc->ctx, hgc->ctx.datasize);
127 enlargecontext(&hgc->ctx, hgc->ctx.datasize);
126
128
127 if (isupper(hgc->ctx.ch) && hgc->ctx.ch != 'S')
129 if (isupper(hgc->ctx.ch) && hgc->ctx.ch != 'S') {
128 return; /* assumes input request */
130 return; /* assumes input request */
131 }
129
132
130 size_t cursize = 0;
133 size_t cursize = 0;
131 while (cursize < hgc->ctx.datasize) {
134 while (cursize < hgc->ctx.datasize) {
132 rsize = recv(hgc->sockfd, hgc->ctx.data + cursize,
135 rsize = recv(hgc->sockfd, hgc->ctx.data + cursize,
133 hgc->ctx.datasize - cursize, 0);
136 hgc->ctx.datasize - cursize, 0);
134 if (rsize < 1)
137 if (rsize < 1) {
135 abortmsg("failed to read data block");
138 abortmsg("failed to read data block");
139 }
136 cursize += rsize;
140 cursize += rsize;
137 }
141 }
138 }
142 }
@@ -143,8 +147,9 b' static void sendall(int sockfd, const vo'
143 const char *const endp = p + datasize;
147 const char *const endp = p + datasize;
144 while (p < endp) {
148 while (p < endp) {
145 ssize_t r = send(sockfd, p, endp - p, 0);
149 ssize_t r = send(sockfd, p, endp - p, 0);
146 if (r < 0)
150 if (r < 0) {
147 abortmsgerrno("cannot communicate");
151 abortmsgerrno("cannot communicate");
152 }
148 p += r;
153 p += r;
149 }
154 }
150 }
155 }
@@ -186,8 +191,9 b' static void packcmdargs(context_t *ctx, '
186 ctx->datasize += n;
191 ctx->datasize += n;
187 }
192 }
188
193
189 if (ctx->datasize > 0)
194 if (ctx->datasize > 0) {
190 --ctx->datasize; /* strip last '\0' */
195 --ctx->datasize; /* strip last '\0' */
196 }
191 }
197 }
192
198
193 /* Extract '\0'-separated list of args to new buffer, terminated by NULL */
199 /* Extract '\0'-separated list of args to new buffer, terminated by NULL */
@@ -205,8 +211,9 b' static const char **unpackcmdargsnul(con'
205 args[nargs] = s;
211 args[nargs] = s;
206 nargs++;
212 nargs++;
207 s = memchr(s, '\0', e - s);
213 s = memchr(s, '\0', e - s);
208 if (!s)
214 if (!s) {
209 break;
215 break;
216 }
210 s++;
217 s++;
211 }
218 }
212 args[nargs] = NULL;
219 args[nargs] = NULL;
@@ -225,8 +232,9 b' static void handlereadrequest(hgclient_t'
225 static void handlereadlinerequest(hgclient_t *hgc)
232 static void handlereadlinerequest(hgclient_t *hgc)
226 {
233 {
227 context_t *ctx = &hgc->ctx;
234 context_t *ctx = &hgc->ctx;
228 if (!fgets(ctx->data, ctx->datasize, stdin))
235 if (!fgets(ctx->data, ctx->datasize, stdin)) {
229 ctx->data[0] = '\0';
236 ctx->data[0] = '\0';
237 }
230 ctx->datasize = strlen(ctx->data);
238 ctx->datasize = strlen(ctx->data);
231 writeblock(hgc);
239 writeblock(hgc);
232 }
240 }
@@ -239,8 +247,9 b' static void handlesystemrequest(hgclient'
239 ctx->data[ctx->datasize] = '\0'; /* terminate last string */
247 ctx->data[ctx->datasize] = '\0'; /* terminate last string */
240
248
241 const char **args = unpackcmdargsnul(ctx);
249 const char **args = unpackcmdargsnul(ctx);
242 if (!args[0] || !args[1] || !args[2])
250 if (!args[0] || !args[1] || !args[2]) {
243 abortmsg("missing type or command or cwd in system request");
251 abortmsg("missing type or command or cwd in system request");
252 }
244 if (strcmp(args[0], "system") == 0) {
253 if (strcmp(args[0], "system") == 0) {
245 debugmsg("run '%s' at '%s'", args[1], args[2]);
254 debugmsg("run '%s' at '%s'", args[1], args[2]);
246 int32_t r = runshellcmd(args[1], args + 3, args[2]);
255 int32_t r = runshellcmd(args[1], args + 3, args[2]);
@@ -252,8 +261,9 b' static void handlesystemrequest(hgclient'
252 writeblock(hgc);
261 writeblock(hgc);
253 } else if (strcmp(args[0], "pager") == 0) {
262 } else if (strcmp(args[0], "pager") == 0) {
254 setuppager(args[1], args + 3);
263 setuppager(args[1], args + 3);
255 if (hgc->capflags & CAP_ATTACHIO)
264 if (hgc->capflags & CAP_ATTACHIO) {
256 attachio(hgc);
265 attachio(hgc);
266 }
257 /* unblock the server */
267 /* unblock the server */
258 static const char emptycmd[] = "\n";
268 static const char emptycmd[] = "\n";
259 sendall(hgc->sockfd, emptycmd, sizeof(emptycmd) - 1);
269 sendall(hgc->sockfd, emptycmd, sizeof(emptycmd) - 1);
@@ -296,9 +306,10 b' static void handleresponse(hgclient_t *h'
296 handlesystemrequest(hgc);
306 handlesystemrequest(hgc);
297 break;
307 break;
298 default:
308 default:
299 if (isupper(ctx->ch))
309 if (isupper(ctx->ch)) {
300 abortmsg("cannot handle response (ch = %c)",
310 abortmsg("cannot handle response (ch = %c)",
301 ctx->ch);
311 ctx->ch);
312 }
302 }
313 }
303 }
314 }
304 }
315 }
@@ -308,8 +319,9 b' static unsigned int parsecapabilities(co'
308 unsigned int flags = 0;
319 unsigned int flags = 0;
309 while (s < e) {
320 while (s < e) {
310 const char *t = strchr(s, ' ');
321 const char *t = strchr(s, ' ');
311 if (!t || t > e)
322 if (!t || t > e) {
312 t = e;
323 t = e;
324 }
313 const cappair_t *cap;
325 const cappair_t *cap;
314 for (cap = captable; cap->flag; ++cap) {
326 for (cap = captable; cap->flag; ++cap) {
315 size_t n = t - s;
327 size_t n = t - s;
@@ -346,11 +358,13 b' static void readhello(hgclient_t *hgc)'
346 const char *const dataend = ctx->data + ctx->datasize;
358 const char *const dataend = ctx->data + ctx->datasize;
347 while (s < dataend) {
359 while (s < dataend) {
348 const char *t = strchr(s, ':');
360 const char *t = strchr(s, ':');
349 if (!t || t[1] != ' ')
361 if (!t || t[1] != ' ') {
350 break;
362 break;
363 }
351 const char *u = strchr(t + 2, '\n');
364 const char *u = strchr(t + 2, '\n');
352 if (!u)
365 if (!u) {
353 u = dataend;
366 u = dataend;
367 }
354 if (strncmp(s, "capabilities:", t - s + 1) == 0) {
368 if (strncmp(s, "capabilities:", t - s + 1) == 0) {
355 hgc->capflags = parsecapabilities(t + 2, u);
369 hgc->capflags = parsecapabilities(t + 2, u);
356 } else if (strncmp(s, "pgid:", t - s + 1) == 0) {
370 } else if (strncmp(s, "pgid:", t - s + 1) == 0) {
@@ -367,8 +381,9 b' static void updateprocname(hgclient_t *h'
367 {
381 {
368 int r = snprintf(hgc->ctx.data, hgc->ctx.maxdatasize, "chg[worker/%d]",
382 int r = snprintf(hgc->ctx.data, hgc->ctx.maxdatasize, "chg[worker/%d]",
369 (int)getpid());
383 (int)getpid());
370 if (r < 0 || (size_t)r >= hgc->ctx.maxdatasize)
384 if (r < 0 || (size_t)r >= hgc->ctx.maxdatasize) {
371 abortmsg("insufficient buffer to write procname (r = %d)", r);
385 abortmsg("insufficient buffer to write procname (r = %d)", r);
386 }
372 hgc->ctx.datasize = (size_t)r;
387 hgc->ctx.datasize = (size_t)r;
373 writeblockrequest(hgc, "setprocname");
388 writeblockrequest(hgc, "setprocname");
374 }
389 }
@@ -380,8 +395,9 b' static void attachio(hgclient_t *hgc)'
380 sendall(hgc->sockfd, chcmd, sizeof(chcmd) - 1);
395 sendall(hgc->sockfd, chcmd, sizeof(chcmd) - 1);
381 readchannel(hgc);
396 readchannel(hgc);
382 context_t *ctx = &hgc->ctx;
397 context_t *ctx = &hgc->ctx;
383 if (ctx->ch != 'I')
398 if (ctx->ch != 'I') {
384 abortmsg("unexpected response for attachio (ch = %c)", ctx->ch);
399 abortmsg("unexpected response for attachio (ch = %c)", ctx->ch);
400 }
385
401
386 static const int fds[3] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO};
402 static const int fds[3] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO};
387 struct msghdr msgh;
403 struct msghdr msgh;
@@ -399,23 +415,27 b' static void attachio(hgclient_t *hgc)'
399 memcpy(CMSG_DATA(cmsg), fds, sizeof(fds));
415 memcpy(CMSG_DATA(cmsg), fds, sizeof(fds));
400 msgh.msg_controllen = cmsg->cmsg_len;
416 msgh.msg_controllen = cmsg->cmsg_len;
401 ssize_t r = sendmsg(hgc->sockfd, &msgh, 0);
417 ssize_t r = sendmsg(hgc->sockfd, &msgh, 0);
402 if (r < 0)
418 if (r < 0) {
403 abortmsgerrno("sendmsg failed");
419 abortmsgerrno("sendmsg failed");
420 }
404
421
405 handleresponse(hgc);
422 handleresponse(hgc);
406 int32_t n;
423 int32_t n;
407 if (ctx->datasize != sizeof(n))
424 if (ctx->datasize != sizeof(n)) {
408 abortmsg("unexpected size of attachio result");
425 abortmsg("unexpected size of attachio result");
426 }
409 memcpy(&n, ctx->data, sizeof(n));
427 memcpy(&n, ctx->data, sizeof(n));
410 n = ntohl(n);
428 n = ntohl(n);
411 if (n != sizeof(fds) / sizeof(fds[0]))
429 if (n != sizeof(fds) / sizeof(fds[0])) {
412 abortmsg("failed to send fds (n = %d)", n);
430 abortmsg("failed to send fds (n = %d)", n);
431 }
413 }
432 }
414
433
415 static void chdirtocwd(hgclient_t *hgc)
434 static void chdirtocwd(hgclient_t *hgc)
416 {
435 {
417 if (!getcwd(hgc->ctx.data, hgc->ctx.maxdatasize))
436 if (!getcwd(hgc->ctx.data, hgc->ctx.maxdatasize)) {
418 abortmsgerrno("failed to getcwd");
437 abortmsgerrno("failed to getcwd");
438 }
419 hgc->ctx.datasize = strlen(hgc->ctx.data);
439 hgc->ctx.datasize = strlen(hgc->ctx.data);
420 writeblockrequest(hgc, "chdir");
440 writeblockrequest(hgc, "chdir");
421 }
441 }
@@ -440,8 +460,9 b' static void forwardumask(hgclient_t *hgc'
440 hgclient_t *hgc_open(const char *sockname)
460 hgclient_t *hgc_open(const char *sockname)
441 {
461 {
442 int fd = socket(AF_UNIX, SOCK_STREAM, 0);
462 int fd = socket(AF_UNIX, SOCK_STREAM, 0);
443 if (fd < 0)
463 if (fd < 0) {
444 abortmsgerrno("cannot create socket");
464 abortmsgerrno("cannot create socket");
465 }
445
466
446 /* don't keep fd on fork(), so that it can be closed when the parent
467 /* don't keep fd on fork(), so that it can be closed when the parent
447 * process get terminated. */
468 * process get terminated. */
@@ -456,34 +477,39 b' hgclient_t *hgc_open(const char *socknam'
456 {
477 {
457 const char *split = strrchr(sockname, '/');
478 const char *split = strrchr(sockname, '/');
458 if (split && split != sockname) {
479 if (split && split != sockname) {
459 if (split[1] == '\0')
480 if (split[1] == '\0') {
460 abortmsg("sockname cannot end with a slash");
481 abortmsg("sockname cannot end with a slash");
482 }
461 size_t len = split - sockname;
483 size_t len = split - sockname;
462 char sockdir[len + 1];
484 char sockdir[len + 1];
463 memcpy(sockdir, sockname, len);
485 memcpy(sockdir, sockname, len);
464 sockdir[len] = '\0';
486 sockdir[len] = '\0';
465
487
466 bakfd = open(".", O_DIRECTORY);
488 bakfd = open(".", O_DIRECTORY);
467 if (bakfd == -1)
489 if (bakfd == -1) {
468 abortmsgerrno("cannot open cwd");
490 abortmsgerrno("cannot open cwd");
491 }
469
492
470 int r = chdir(sockdir);
493 int r = chdir(sockdir);
471 if (r != 0)
494 if (r != 0) {
472 abortmsgerrno("cannot chdir %s", sockdir);
495 abortmsgerrno("cannot chdir %s", sockdir);
496 }
473
497
474 basename = split + 1;
498 basename = split + 1;
475 }
499 }
476 }
500 }
477 if (strlen(basename) >= sizeof(addr.sun_path))
501 if (strlen(basename) >= sizeof(addr.sun_path)) {
478 abortmsg("sockname is too long: %s", basename);
502 abortmsg("sockname is too long: %s", basename);
503 }
479 strncpy(addr.sun_path, basename, sizeof(addr.sun_path));
504 strncpy(addr.sun_path, basename, sizeof(addr.sun_path));
480 addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
505 addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
481
506
482 /* real connect */
507 /* real connect */
483 int r = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
508 int r = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
484 if (r < 0) {
509 if (r < 0) {
485 if (errno != ENOENT && errno != ECONNREFUSED)
510 if (errno != ENOENT && errno != ECONNREFUSED) {
486 abortmsgerrno("cannot connect to %s", sockname);
511 abortmsgerrno("cannot connect to %s", sockname);
512 }
487 }
513 }
488 if (bakfd != -1) {
514 if (bakfd != -1) {
489 fchdirx(bakfd);
515 fchdirx(bakfd);
@@ -501,16 +527,21 b' hgclient_t *hgc_open(const char *socknam'
501 initcontext(&hgc->ctx);
527 initcontext(&hgc->ctx);
502
528
503 readhello(hgc);
529 readhello(hgc);
504 if (!(hgc->capflags & CAP_RUNCOMMAND))
530 if (!(hgc->capflags & CAP_RUNCOMMAND)) {
505 abortmsg("insufficient capability: runcommand");
531 abortmsg("insufficient capability: runcommand");
506 if (hgc->capflags & CAP_SETPROCNAME)
532 }
533 if (hgc->capflags & CAP_SETPROCNAME) {
507 updateprocname(hgc);
534 updateprocname(hgc);
508 if (hgc->capflags & CAP_ATTACHIO)
535 }
536 if (hgc->capflags & CAP_ATTACHIO) {
509 attachio(hgc);
537 attachio(hgc);
510 if (hgc->capflags & CAP_CHDIR)
538 }
539 if (hgc->capflags & CAP_CHDIR) {
511 chdirtocwd(hgc);
540 chdirtocwd(hgc);
512 if (hgc->capflags & CAP_SETUMASK2)
541 }
542 if (hgc->capflags & CAP_SETUMASK2) {
513 forwardumask(hgc);
543 forwardumask(hgc);
544 }
514
545
515 return hgc;
546 return hgc;
516 }
547 }
@@ -555,16 +586,18 b' const char **hgc_validate(hgclient_t *hg'
555 size_t argsize)
586 size_t argsize)
556 {
587 {
557 assert(hgc);
588 assert(hgc);
558 if (!(hgc->capflags & CAP_VALIDATE))
589 if (!(hgc->capflags & CAP_VALIDATE)) {
559 return NULL;
590 return NULL;
591 }
560
592
561 packcmdargs(&hgc->ctx, args, argsize);
593 packcmdargs(&hgc->ctx, args, argsize);
562 writeblockrequest(hgc, "validate");
594 writeblockrequest(hgc, "validate");
563 handleresponse(hgc);
595 handleresponse(hgc);
564
596
565 /* the server returns '\0' if it can handle our request */
597 /* the server returns '\0' if it can handle our request */
566 if (hgc->ctx.datasize <= 1)
598 if (hgc->ctx.datasize <= 1) {
567 return NULL;
599 return NULL;
600 }
568
601
569 /* make sure the buffer is '\0' terminated */
602 /* make sure the buffer is '\0' terminated */
570 enlargecontext(&hgc->ctx, hgc->ctx.datasize + 1);
603 enlargecontext(&hgc->ctx, hgc->ctx.datasize + 1);
@@ -599,8 +632,9 b' int hgc_runcommand(hgclient_t *hgc, cons'
599 void hgc_attachio(hgclient_t *hgc)
632 void hgc_attachio(hgclient_t *hgc)
600 {
633 {
601 assert(hgc);
634 assert(hgc);
602 if (!(hgc->capflags & CAP_ATTACHIO))
635 if (!(hgc->capflags & CAP_ATTACHIO)) {
603 return;
636 return;
637 }
604 attachio(hgc);
638 attachio(hgc);
605 }
639 }
606
640
@@ -613,8 +647,9 b' void hgc_attachio(hgclient_t *hgc)'
613 void hgc_setenv(hgclient_t *hgc, const char *const envp[])
647 void hgc_setenv(hgclient_t *hgc, const char *const envp[])
614 {
648 {
615 assert(hgc && envp);
649 assert(hgc && envp);
616 if (!(hgc->capflags & CAP_SETENV))
650 if (!(hgc->capflags & CAP_SETENV)) {
617 return;
651 return;
652 }
618 packcmdargs(&hgc->ctx, envp, /*argsize*/ -1);
653 packcmdargs(&hgc->ctx, envp, /*argsize*/ -1);
619 writeblockrequest(hgc, "setenv");
654 writeblockrequest(hgc, "setenv");
620 }
655 }
@@ -25,8 +25,9 b' static pid_t peerpid = 0;'
25 static void forwardsignal(int sig)
25 static void forwardsignal(int sig)
26 {
26 {
27 assert(peerpid > 0);
27 assert(peerpid > 0);
28 if (kill(peerpid, sig) < 0)
28 if (kill(peerpid, sig) < 0) {
29 abortmsgerrno("cannot kill %d", peerpid);
29 abortmsgerrno("cannot kill %d", peerpid);
30 }
30 debugmsg("forward signal %d", sig);
31 debugmsg("forward signal %d", sig);
31 }
32 }
32
33
@@ -34,8 +35,9 b' static void forwardsignaltogroup(int sig'
34 {
35 {
35 /* prefer kill(-pgid, sig), fallback to pid if pgid is invalid */
36 /* prefer kill(-pgid, sig), fallback to pid if pgid is invalid */
36 pid_t killpid = peerpgid > 1 ? -peerpgid : peerpid;
37 pid_t killpid = peerpgid > 1 ? -peerpgid : peerpid;
37 if (kill(killpid, sig) < 0)
38 if (kill(killpid, sig) < 0) {
38 abortmsgerrno("cannot kill %d", killpid);
39 abortmsgerrno("cannot kill %d", killpid);
40 }
39 debugmsg("forward signal %d to %d", sig, killpid);
41 debugmsg("forward signal %d to %d", sig, killpid);
40 }
42 }
41
43
@@ -43,28 +45,36 b' static void handlestopsignal(int sig)'
43 {
45 {
44 sigset_t unblockset, oldset;
46 sigset_t unblockset, oldset;
45 struct sigaction sa, oldsa;
47 struct sigaction sa, oldsa;
46 if (sigemptyset(&unblockset) < 0)
48 if (sigemptyset(&unblockset) < 0) {
47 goto error;
49 goto error;
48 if (sigaddset(&unblockset, sig) < 0)
50 }
51 if (sigaddset(&unblockset, sig) < 0) {
49 goto error;
52 goto error;
53 }
50 memset(&sa, 0, sizeof(sa));
54 memset(&sa, 0, sizeof(sa));
51 sa.sa_handler = SIG_DFL;
55 sa.sa_handler = SIG_DFL;
52 sa.sa_flags = SA_RESTART;
56 sa.sa_flags = SA_RESTART;
53 if (sigemptyset(&sa.sa_mask) < 0)
57 if (sigemptyset(&sa.sa_mask) < 0) {
54 goto error;
58 goto error;
59 }
55
60
56 forwardsignal(sig);
61 forwardsignal(sig);
57 if (raise(sig) < 0) /* resend to self */
62 if (raise(sig) < 0) { /* resend to self */
58 goto error;
63 goto error;
59 if (sigaction(sig, &sa, &oldsa) < 0)
64 }
65 if (sigaction(sig, &sa, &oldsa) < 0) {
60 goto error;
66 goto error;
61 if (sigprocmask(SIG_UNBLOCK, &unblockset, &oldset) < 0)
67 }
68 if (sigprocmask(SIG_UNBLOCK, &unblockset, &oldset) < 0) {
62 goto error;
69 goto error;
70 }
63 /* resent signal will be handled before sigprocmask() returns */
71 /* resent signal will be handled before sigprocmask() returns */
64 if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0)
72 if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0) {
65 goto error;
73 goto error;
66 if (sigaction(sig, &oldsa, NULL) < 0)
74 }
75 if (sigaction(sig, &oldsa, NULL) < 0) {
67 goto error;
76 goto error;
77 }
68 return;
78 return;
69
79
70 error:
80 error:
@@ -73,19 +83,22 b' error:'
73
83
74 static void handlechildsignal(int sig UNUSED_)
84 static void handlechildsignal(int sig UNUSED_)
75 {
85 {
76 if (peerpid == 0 || pagerpid == 0)
86 if (peerpid == 0 || pagerpid == 0) {
77 return;
87 return;
88 }
78 /* if pager exits, notify the server with SIGPIPE immediately.
89 /* if pager exits, notify the server with SIGPIPE immediately.
79 * otherwise the server won't get SIGPIPE if it does not write
90 * otherwise the server won't get SIGPIPE if it does not write
80 * anything. (issue5278) */
91 * anything. (issue5278) */
81 if (waitpid(pagerpid, NULL, WNOHANG) == pagerpid)
92 if (waitpid(pagerpid, NULL, WNOHANG) == pagerpid) {
82 kill(peerpid, SIGPIPE);
93 kill(peerpid, SIGPIPE);
94 }
83 }
95 }
84
96
85 void setupsignalhandler(pid_t pid, pid_t pgid)
97 void setupsignalhandler(pid_t pid, pid_t pgid)
86 {
98 {
87 if (pid <= 0)
99 if (pid <= 0) {
88 return;
100 return;
101 }
89 peerpid = pid;
102 peerpid = pid;
90 peerpgid = (pgid <= 1 ? 0 : pgid);
103 peerpgid = (pgid <= 1 ? 0 : pgid);
91
104
@@ -98,42 +111,52 b' void setupsignalhandler(pid_t pid, pid_t'
98 * - SIGINT: usually generated by the terminal */
111 * - SIGINT: usually generated by the terminal */
99 sa.sa_handler = forwardsignaltogroup;
112 sa.sa_handler = forwardsignaltogroup;
100 sa.sa_flags = SA_RESTART;
113 sa.sa_flags = SA_RESTART;
101 if (sigemptyset(&sa.sa_mask) < 0)
114 if (sigemptyset(&sa.sa_mask) < 0) {
115 goto error;
116 }
117 if (sigaction(SIGHUP, &sa, NULL) < 0) {
102 goto error;
118 goto error;
103 if (sigaction(SIGHUP, &sa, NULL) < 0)
119 }
120 if (sigaction(SIGINT, &sa, NULL) < 0) {
104 goto error;
121 goto error;
105 if (sigaction(SIGINT, &sa, NULL) < 0)
122 }
106 goto error;
107
123
108 /* terminate frontend by double SIGTERM in case of server freeze */
124 /* terminate frontend by double SIGTERM in case of server freeze */
109 sa.sa_handler = forwardsignal;
125 sa.sa_handler = forwardsignal;
110 sa.sa_flags |= SA_RESETHAND;
126 sa.sa_flags |= SA_RESETHAND;
111 if (sigaction(SIGTERM, &sa, NULL) < 0)
127 if (sigaction(SIGTERM, &sa, NULL) < 0) {
112 goto error;
128 goto error;
129 }
113
130
114 /* notify the worker about window resize events */
131 /* notify the worker about window resize events */
115 sa.sa_flags = SA_RESTART;
132 sa.sa_flags = SA_RESTART;
116 if (sigaction(SIGWINCH, &sa, NULL) < 0)
133 if (sigaction(SIGWINCH, &sa, NULL) < 0) {
117 goto error;
134 goto error;
135 }
118 /* forward user-defined signals */
136 /* forward user-defined signals */
119 if (sigaction(SIGUSR1, &sa, NULL) < 0)
137 if (sigaction(SIGUSR1, &sa, NULL) < 0) {
120 goto error;
138 goto error;
121 if (sigaction(SIGUSR2, &sa, NULL) < 0)
139 }
140 if (sigaction(SIGUSR2, &sa, NULL) < 0) {
122 goto error;
141 goto error;
142 }
123 /* propagate job control requests to worker */
143 /* propagate job control requests to worker */
124 sa.sa_handler = forwardsignal;
144 sa.sa_handler = forwardsignal;
125 sa.sa_flags = SA_RESTART;
145 sa.sa_flags = SA_RESTART;
126 if (sigaction(SIGCONT, &sa, NULL) < 0)
146 if (sigaction(SIGCONT, &sa, NULL) < 0) {
127 goto error;
147 goto error;
148 }
128 sa.sa_handler = handlestopsignal;
149 sa.sa_handler = handlestopsignal;
129 sa.sa_flags = SA_RESTART;
150 sa.sa_flags = SA_RESTART;
130 if (sigaction(SIGTSTP, &sa, NULL) < 0)
151 if (sigaction(SIGTSTP, &sa, NULL) < 0) {
131 goto error;
152 goto error;
153 }
132 /* get notified when pager exits */
154 /* get notified when pager exits */
133 sa.sa_handler = handlechildsignal;
155 sa.sa_handler = handlechildsignal;
134 sa.sa_flags = SA_RESTART;
156 sa.sa_flags = SA_RESTART;
135 if (sigaction(SIGCHLD, &sa, NULL) < 0)
157 if (sigaction(SIGCHLD, &sa, NULL) < 0) {
136 goto error;
158 goto error;
159 }
137
160
138 return;
161 return;
139
162
@@ -147,26 +170,34 b' void restoresignalhandler(void)'
147 memset(&sa, 0, sizeof(sa));
170 memset(&sa, 0, sizeof(sa));
148 sa.sa_handler = SIG_DFL;
171 sa.sa_handler = SIG_DFL;
149 sa.sa_flags = SA_RESTART;
172 sa.sa_flags = SA_RESTART;
150 if (sigemptyset(&sa.sa_mask) < 0)
173 if (sigemptyset(&sa.sa_mask) < 0) {
151 goto error;
174 goto error;
175 }
152
176
153 if (sigaction(SIGHUP, &sa, NULL) < 0)
177 if (sigaction(SIGHUP, &sa, NULL) < 0) {
154 goto error;
178 goto error;
155 if (sigaction(SIGTERM, &sa, NULL) < 0)
179 }
180 if (sigaction(SIGTERM, &sa, NULL) < 0) {
156 goto error;
181 goto error;
157 if (sigaction(SIGWINCH, &sa, NULL) < 0)
182 }
183 if (sigaction(SIGWINCH, &sa, NULL) < 0) {
158 goto error;
184 goto error;
159 if (sigaction(SIGCONT, &sa, NULL) < 0)
185 }
186 if (sigaction(SIGCONT, &sa, NULL) < 0) {
160 goto error;
187 goto error;
161 if (sigaction(SIGTSTP, &sa, NULL) < 0)
188 }
189 if (sigaction(SIGTSTP, &sa, NULL) < 0) {
162 goto error;
190 goto error;
163 if (sigaction(SIGCHLD, &sa, NULL) < 0)
191 }
192 if (sigaction(SIGCHLD, &sa, NULL) < 0) {
164 goto error;
193 goto error;
194 }
165
195
166 /* ignore Ctrl+C while shutting down to make pager exits cleanly */
196 /* ignore Ctrl+C while shutting down to make pager exits cleanly */
167 sa.sa_handler = SIG_IGN;
197 sa.sa_handler = SIG_IGN;
168 if (sigaction(SIGINT, &sa, NULL) < 0)
198 if (sigaction(SIGINT, &sa, NULL) < 0) {
169 goto error;
199 goto error;
200 }
170
201
171 peerpid = 0;
202 peerpid = 0;
172 return;
203 return;
@@ -180,22 +211,27 b' error:'
180 pid_t setuppager(const char *pagercmd, const char *envp[])
211 pid_t setuppager(const char *pagercmd, const char *envp[])
181 {
212 {
182 assert(pagerpid == 0);
213 assert(pagerpid == 0);
183 if (!pagercmd)
214 if (!pagercmd) {
184 return 0;
215 return 0;
216 }
185
217
186 int pipefds[2];
218 int pipefds[2];
187 if (pipe(pipefds) < 0)
219 if (pipe(pipefds) < 0) {
188 return 0;
220 return 0;
221 }
189 pid_t pid = fork();
222 pid_t pid = fork();
190 if (pid < 0)
223 if (pid < 0) {
191 goto error;
224 goto error;
225 }
192 if (pid > 0) {
226 if (pid > 0) {
193 close(pipefds[0]);
227 close(pipefds[0]);
194 if (dup2(pipefds[1], fileno(stdout)) < 0)
228 if (dup2(pipefds[1], fileno(stdout)) < 0) {
195 goto error;
229 goto error;
230 }
196 if (isatty(fileno(stderr))) {
231 if (isatty(fileno(stderr))) {
197 if (dup2(pipefds[1], fileno(stderr)) < 0)
232 if (dup2(pipefds[1], fileno(stderr)) < 0) {
198 goto error;
233 goto error;
234 }
199 }
235 }
200 close(pipefds[1]);
236 close(pipefds[1]);
201 pagerpid = pid;
237 pagerpid = pid;
@@ -222,16 +258,18 b' error:'
222
258
223 void waitpager(void)
259 void waitpager(void)
224 {
260 {
225 if (pagerpid == 0)
261 if (pagerpid == 0) {
226 return;
262 return;
263 }
227
264
228 /* close output streams to notify the pager its input ends */
265 /* close output streams to notify the pager its input ends */
229 fclose(stdout);
266 fclose(stdout);
230 fclose(stderr);
267 fclose(stderr);
231 while (1) {
268 while (1) {
232 pid_t ret = waitpid(pagerpid, NULL, 0);
269 pid_t ret = waitpid(pagerpid, NULL, 0);
233 if (ret == -1 && errno == EINTR)
270 if (ret == -1 && errno == EINTR) {
234 continue;
271 continue;
272 }
235 break;
273 break;
236 }
274 }
237 }
275 }
@@ -25,8 +25,9 b' static int colorenabled = 0;'
25
25
26 static inline void fsetcolor(FILE *fp, const char *code)
26 static inline void fsetcolor(FILE *fp, const char *code)
27 {
27 {
28 if (!colorenabled)
28 if (!colorenabled) {
29 return;
29 return;
30 }
30 fprintf(fp, "\033[%sm", code);
31 fprintf(fp, "\033[%sm", code);
31 }
32 }
32
33
@@ -35,8 +36,9 b' static void vabortmsgerrno(int no, const'
35 fsetcolor(stderr, "1;31");
36 fsetcolor(stderr, "1;31");
36 fputs("chg: abort: ", stderr);
37 fputs("chg: abort: ", stderr);
37 vfprintf(stderr, fmt, args);
38 vfprintf(stderr, fmt, args);
38 if (no != 0)
39 if (no != 0) {
39 fprintf(stderr, " (errno = %d, %s)", no, strerror(no));
40 fprintf(stderr, " (errno = %d, %s)", no, strerror(no));
41 }
40 fsetcolor(stderr, "");
42 fsetcolor(stderr, "");
41 fputc('\n', stderr);
43 fputc('\n', stderr);
42 exit(255);
44 exit(255);
@@ -82,8 +84,9 b' void enabledebugmsg(void)'
82
84
83 void debugmsg(const char *fmt, ...)
85 void debugmsg(const char *fmt, ...)
84 {
86 {
85 if (!debugmsgenabled)
87 if (!debugmsgenabled) {
86 return;
88 return;
89 }
87
90
88 va_list args;
91 va_list args;
89 va_start(args, fmt);
92 va_start(args, fmt);
@@ -98,32 +101,37 b' void debugmsg(const char *fmt, ...)'
98 void fchdirx(int dirfd)
101 void fchdirx(int dirfd)
99 {
102 {
100 int r = fchdir(dirfd);
103 int r = fchdir(dirfd);
101 if (r == -1)
104 if (r == -1) {
102 abortmsgerrno("failed to fchdir");
105 abortmsgerrno("failed to fchdir");
106 }
103 }
107 }
104
108
105 void fsetcloexec(int fd)
109 void fsetcloexec(int fd)
106 {
110 {
107 int flags = fcntl(fd, F_GETFD);
111 int flags = fcntl(fd, F_GETFD);
108 if (flags < 0)
112 if (flags < 0) {
109 abortmsgerrno("cannot get flags of fd %d", fd);
113 abortmsgerrno("cannot get flags of fd %d", fd);
110 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
114 }
115 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
111 abortmsgerrno("cannot set flags of fd %d", fd);
116 abortmsgerrno("cannot set flags of fd %d", fd);
117 }
112 }
118 }
113
119
114 void *mallocx(size_t size)
120 void *mallocx(size_t size)
115 {
121 {
116 void *result = malloc(size);
122 void *result = malloc(size);
117 if (!result)
123 if (!result) {
118 abortmsg("failed to malloc");
124 abortmsg("failed to malloc");
125 }
119 return result;
126 return result;
120 }
127 }
121
128
122 void *reallocx(void *ptr, size_t size)
129 void *reallocx(void *ptr, size_t size)
123 {
130 {
124 void *result = realloc(ptr, size);
131 void *result = realloc(ptr, size);
125 if (!result)
132 if (!result) {
126 abortmsg("failed to realloc");
133 abortmsg("failed to realloc");
134 }
127 return result;
135 return result;
128 }
136 }
129
137
@@ -144,30 +152,37 b' int runshellcmd(const char *cmd, const c'
144 memset(&newsa, 0, sizeof(newsa));
152 memset(&newsa, 0, sizeof(newsa));
145 newsa.sa_handler = SIG_IGN;
153 newsa.sa_handler = SIG_IGN;
146 newsa.sa_flags = 0;
154 newsa.sa_flags = 0;
147 if (sigemptyset(&newsa.sa_mask) < 0)
155 if (sigemptyset(&newsa.sa_mask) < 0) {
148 goto done;
156 goto done;
149 if (sigaction(SIGINT, &newsa, &oldsaint) < 0)
157 }
158 if (sigaction(SIGINT, &newsa, &oldsaint) < 0) {
150 goto done;
159 goto done;
160 }
151 doneflags |= F_SIGINT;
161 doneflags |= F_SIGINT;
152 if (sigaction(SIGQUIT, &newsa, &oldsaquit) < 0)
162 if (sigaction(SIGQUIT, &newsa, &oldsaquit) < 0) {
153 goto done;
163 goto done;
164 }
154 doneflags |= F_SIGQUIT;
165 doneflags |= F_SIGQUIT;
155
166
156 if (sigaddset(&newsa.sa_mask, SIGCHLD) < 0)
167 if (sigaddset(&newsa.sa_mask, SIGCHLD) < 0) {
157 goto done;
168 goto done;
158 if (sigprocmask(SIG_BLOCK, &newsa.sa_mask, &oldmask) < 0)
169 }
170 if (sigprocmask(SIG_BLOCK, &newsa.sa_mask, &oldmask) < 0) {
159 goto done;
171 goto done;
172 }
160 doneflags |= F_SIGMASK;
173 doneflags |= F_SIGMASK;
161
174
162 pid_t pid = fork();
175 pid_t pid = fork();
163 if (pid < 0)
176 if (pid < 0) {
164 goto done;
177 goto done;
178 }
165 if (pid == 0) {
179 if (pid == 0) {
166 sigaction(SIGINT, &oldsaint, NULL);
180 sigaction(SIGINT, &oldsaint, NULL);
167 sigaction(SIGQUIT, &oldsaquit, NULL);
181 sigaction(SIGQUIT, &oldsaquit, NULL);
168 sigprocmask(SIG_SETMASK, &oldmask, NULL);
182 sigprocmask(SIG_SETMASK, &oldmask, NULL);
169 if (cwd && chdir(cwd) < 0)
183 if (cwd && chdir(cwd) < 0) {
170 _exit(127);
184 _exit(127);
185 }
171 const char *argv[] = {"sh", "-c", cmd, NULL};
186 const char *argv[] = {"sh", "-c", cmd, NULL};
172 if (envp) {
187 if (envp) {
173 execve("/bin/sh", (char **)argv, (char **)envp);
188 execve("/bin/sh", (char **)argv, (char **)envp);
@@ -176,25 +191,32 b' int runshellcmd(const char *cmd, const c'
176 }
191 }
177 _exit(127);
192 _exit(127);
178 } else {
193 } else {
179 if (waitpid(pid, &status, 0) < 0)
194 if (waitpid(pid, &status, 0) < 0) {
180 goto done;
195 goto done;
196 }
181 doneflags |= F_WAITPID;
197 doneflags |= F_WAITPID;
182 }
198 }
183
199
184 done:
200 done:
185 if (doneflags & F_SIGINT)
201 if (doneflags & F_SIGINT) {
186 sigaction(SIGINT, &oldsaint, NULL);
202 sigaction(SIGINT, &oldsaint, NULL);
187 if (doneflags & F_SIGQUIT)
203 }
204 if (doneflags & F_SIGQUIT) {
188 sigaction(SIGQUIT, &oldsaquit, NULL);
205 sigaction(SIGQUIT, &oldsaquit, NULL);
189 if (doneflags & F_SIGMASK)
206 }
207 if (doneflags & F_SIGMASK) {
190 sigprocmask(SIG_SETMASK, &oldmask, NULL);
208 sigprocmask(SIG_SETMASK, &oldmask, NULL);
209 }
191
210
192 /* no way to report other errors, use 127 (= shell termination) */
211 /* no way to report other errors, use 127 (= shell termination) */
193 if (!(doneflags & F_WAITPID))
212 if (!(doneflags & F_WAITPID)) {
194 return 127;
213 return 127;
195 if (WIFEXITED(status))
214 }
215 if (WIFEXITED(status)) {
196 return WEXITSTATUS(status);
216 return WEXITSTATUS(status);
197 if (WIFSIGNALED(status))
217 }
218 if (WIFSIGNALED(status)) {
198 return -WTERMSIG(status);
219 return -WTERMSIG(status);
220 }
199 return 127;
221 return 127;
200 }
222 }
@@ -35,15 +35,19 b' int bdiff_splitlines(const char *a, ssiz'
35
35
36 /* count the lines */
36 /* count the lines */
37 i = 1; /* extra line for sentinel */
37 i = 1; /* extra line for sentinel */
38 for (p = a; p < plast; p++)
38 for (p = a; p < plast; p++) {
39 if (*p == '\n')
39 if (*p == '\n') {
40 i++;
40 i++;
41 if (p == plast)
41 }
42 }
43 if (p == plast) {
42 i++;
44 i++;
45 }
43
46
44 *lr = l = (struct bdiff_line *)calloc(i, sizeof(struct bdiff_line));
47 *lr = l = (struct bdiff_line *)calloc(i, sizeof(struct bdiff_line));
45 if (!l)
48 if (!l) {
46 return -1;
49 return -1;
50 }
47
51
48 /* build the line array and calculate hashes */
52 /* build the line array and calculate hashes */
49 hash = 0;
53 hash = 0;
@@ -90,18 +94,21 b' static int equatelines(struct bdiff_line'
90 struct pos *h = NULL;
94 struct pos *h = NULL;
91
95
92 /* build a hash table of the next highest power of 2 */
96 /* build a hash table of the next highest power of 2 */
93 while (buckets < bn + 1)
97 while (buckets < bn + 1) {
94 buckets *= 2;
98 buckets *= 2;
99 }
95
100
96 /* try to allocate a large hash table to avoid collisions */
101 /* try to allocate a large hash table to avoid collisions */
97 for (scale = 4; scale; scale /= 2) {
102 for (scale = 4; scale; scale /= 2) {
98 h = (struct pos *)calloc(buckets, scale * sizeof(struct pos));
103 h = (struct pos *)calloc(buckets, scale * sizeof(struct pos));
99 if (h)
104 if (h) {
100 break;
105 break;
106 }
101 }
107 }
102
108
103 if (!h)
109 if (!h) {
104 return 0;
110 return 0;
111 }
105
112
106 buckets = buckets * scale - 1;
113 buckets = buckets * scale - 1;
107
114
@@ -115,9 +122,11 b' static int equatelines(struct bdiff_line'
115 for (i = 0; i < bn; i++) {
122 for (i = 0; i < bn; i++) {
116 /* find the equivalence class */
123 /* find the equivalence class */
117 for (j = b[i].hash & buckets; h[j].pos != -1;
124 for (j = b[i].hash & buckets; h[j].pos != -1;
118 j = (j + 1) & buckets)
125 j = (j + 1) & buckets) {
119 if (!cmp(b + i, b + h[j].pos))
126 if (!cmp(b + i, b + h[j].pos)) {
120 break;
127 break;
128 }
129 }
121
130
122 /* add to the head of the equivalence class */
131 /* add to the head of the equivalence class */
123 b[i].n = h[j].pos;
132 b[i].n = h[j].pos;
@@ -133,15 +142,18 b' static int equatelines(struct bdiff_line'
133 for (i = 0; i < an; i++) {
142 for (i = 0; i < an; i++) {
134 /* find the equivalence class */
143 /* find the equivalence class */
135 for (j = a[i].hash & buckets; h[j].pos != -1;
144 for (j = a[i].hash & buckets; h[j].pos != -1;
136 j = (j + 1) & buckets)
145 j = (j + 1) & buckets) {
137 if (!cmp(a + i, b + h[j].pos))
146 if (!cmp(a + i, b + h[j].pos)) {
138 break;
147 break;
148 }
149 }
139
150
140 a[i].e = j; /* use equivalence class for quick compare */
151 a[i].e = j; /* use equivalence class for quick compare */
141 if (h[j].len <= t)
152 if (h[j].len <= t) {
142 a[i].n = h[j].pos; /* point to head of match list */
153 a[i].n = h[j].pos; /* point to head of match list */
143 else
154 } else {
144 a[i].n = -1; /* too popular */
155 a[i].n = -1; /* too popular */
156 }
145 }
157 }
146
158
147 /* discard hash tables */
159 /* discard hash tables */
@@ -158,16 +170,18 b' static int longest_match(struct bdiff_li'
158 /* window our search on large regions to better bound
170 /* window our search on large regions to better bound
159 worst-case performance. by choosing a window at the end, we
171 worst-case performance. by choosing a window at the end, we
160 reduce skipping overhead on the b chains. */
172 reduce skipping overhead on the b chains. */
161 if (a2 - a1 > 30000)
173 if (a2 - a1 > 30000) {
162 a1 = a2 - 30000;
174 a1 = a2 - 30000;
175 }
163
176
164 half = (a1 + a2 - 1) / 2;
177 half = (a1 + a2 - 1) / 2;
165 bhalf = (b1 + b2 - 1) / 2;
178 bhalf = (b1 + b2 - 1) / 2;
166
179
167 for (i = a1; i < a2; i++) {
180 for (i = a1; i < a2; i++) {
168 /* skip all lines in b after the current block */
181 /* skip all lines in b after the current block */
169 for (j = a[i].n; j >= b2; j = b[j].n)
182 for (j = a[i].n; j >= b2; j = b[j].n) {
170 ;
183 ;
184 }
171
185
172 /* loop through all lines match a[i] in b */
186 /* loop through all lines match a[i] in b */
173 for (; j >= b1; j = b[j].n) {
187 for (; j >= b1; j = b[j].n) {
@@ -179,8 +193,9 b' static int longest_match(struct bdiff_li'
179 break;
193 break;
180 }
194 }
181 /* previous line mismatch? */
195 /* previous line mismatch? */
182 if (a[i - k].e != b[j - k].e)
196 if (a[i - k].e != b[j - k].e) {
183 break;
197 break;
198 }
184 }
199 }
185
200
186 pos[j].pos = i;
201 pos[j].pos = i;
@@ -212,8 +227,9 b' static int longest_match(struct bdiff_li'
212 }
227 }
213
228
214 /* expand match to include subsequent popular lines */
229 /* expand match to include subsequent popular lines */
215 while (mi + mk < a2 && mj + mk < b2 && a[mi + mk].e == b[mj + mk].e)
230 while (mi + mk < a2 && mj + mk < b2 && a[mi + mk].e == b[mj + mk].e) {
216 mk++;
231 mk++;
232 }
217
233
218 *omi = mi;
234 *omi = mi;
219 *omj = mj;
235 *omj = mj;
@@ -230,18 +246,21 b' static struct bdiff_hunk *recurse(struct'
230 while (1) {
246 while (1) {
231 /* find the longest match in this chunk */
247 /* find the longest match in this chunk */
232 k = longest_match(a, b, pos, a1, a2, b1, b2, &i, &j);
248 k = longest_match(a, b, pos, a1, a2, b1, b2, &i, &j);
233 if (!k)
249 if (!k) {
234 return l;
250 return l;
251 }
235
252
236 /* and recurse on the remaining chunks on either side */
253 /* and recurse on the remaining chunks on either side */
237 l = recurse(a, b, pos, a1, i, b1, j, l);
254 l = recurse(a, b, pos, a1, i, b1, j, l);
238 if (!l)
255 if (!l) {
239 return NULL;
256 return NULL;
257 }
240
258
241 l->next =
259 l->next =
242 (struct bdiff_hunk *)malloc(sizeof(struct bdiff_hunk));
260 (struct bdiff_hunk *)malloc(sizeof(struct bdiff_hunk));
243 if (!l->next)
261 if (!l->next) {
244 return NULL;
262 return NULL;
263 }
245
264
246 l = l->next;
265 l = l->next;
247 l->a1 = i;
266 l->a1 = i;
@@ -271,14 +290,16 b' int bdiff_diff(struct bdiff_line *a, int'
271 /* generate the matching block list */
290 /* generate the matching block list */
272
291
273 curr = recurse(a, b, pos, 0, an, 0, bn, base);
292 curr = recurse(a, b, pos, 0, an, 0, bn, base);
274 if (!curr)
293 if (!curr) {
275 return -1;
294 return -1;
295 }
276
296
277 /* sentinel end hunk */
297 /* sentinel end hunk */
278 curr->next =
298 curr->next =
279 (struct bdiff_hunk *)malloc(sizeof(struct bdiff_hunk));
299 (struct bdiff_hunk *)malloc(sizeof(struct bdiff_hunk));
280 if (!curr->next)
300 if (!curr->next) {
281 return -1;
301 return -1;
302 }
282 curr = curr->next;
303 curr = curr->next;
283 curr->a1 = curr->a2 = an;
304 curr->a1 = curr->a2 = an;
284 curr->b1 = curr->b2 = bn;
305 curr->b1 = curr->b2 = bn;
@@ -291,10 +312,11 b' int bdiff_diff(struct bdiff_line *a, int'
291 for (curr = base->next; curr; curr = curr->next) {
312 for (curr = base->next; curr; curr = curr->next) {
292 struct bdiff_hunk *next = curr->next;
313 struct bdiff_hunk *next = curr->next;
293
314
294 if (!next)
315 if (!next) {
295 break;
316 break;
317 }
296
318
297 if (curr->a2 == next->a1 || curr->b2 == next->b1)
319 if (curr->a2 == next->a1 || curr->b2 == next->b1) {
298 while (curr->a2 < an && curr->b2 < bn &&
320 while (curr->a2 < an && curr->b2 < bn &&
299 next->a1 < next->a2 && next->b1 < next->b2 &&
321 next->a1 < next->a2 && next->b1 < next->b2 &&
300 !cmp(a + curr->a2, b + curr->b2)) {
322 !cmp(a + curr->a2, b + curr->b2)) {
@@ -303,10 +325,12 b' int bdiff_diff(struct bdiff_line *a, int'
303 curr->b2++;
325 curr->b2++;
304 next->b1++;
326 next->b1++;
305 }
327 }
328 }
306 }
329 }
307
330
308 for (curr = base->next; curr; curr = curr->next)
331 for (curr = base->next; curr; curr = curr->next) {
309 count++;
332 count++;
333 }
310 return count;
334 return count;
311 }
335 }
312
336
@@ -24,8 +24,9 b' static void b85prep(void)'
24 unsigned i;
24 unsigned i;
25
25
26 memset(b85dec, 0, sizeof(b85dec));
26 memset(b85dec, 0, sizeof(b85dec));
27 for (i = 0; i < sizeof(b85chars); i++)
27 for (i = 0; i < sizeof(b85chars); i++) {
28 b85dec[(int)(b85chars[i])] = i + 1;
28 b85dec[(int)(b85chars[i])] = i + 1;
29 }
29 }
30 }
30
31
31 static PyObject *b85encode(PyObject *self, PyObject *args)
32 static PyObject *b85encode(PyObject *self, PyObject *args)
@@ -37,19 +38,22 b' static PyObject *b85encode(PyObject *sel'
37 unsigned int acc, val, ch;
38 unsigned int acc, val, ch;
38 int pad = 0;
39 int pad = 0;
39
40
40 if (!PyArg_ParseTuple(args, PY23("s#|i", "y#|i"), &text, &len, &pad))
41 if (!PyArg_ParseTuple(args, PY23("s#|i", "y#|i"), &text, &len, &pad)) {
41 return NULL;
42 return NULL;
43 }
42
44
43 if (pad)
45 if (pad) {
44 olen = ((len + 3) / 4 * 5) - 3;
46 olen = ((len + 3) / 4 * 5) - 3;
45 else {
47 } else {
46 olen = len % 4;
48 olen = len % 4;
47 if (olen)
49 if (olen) {
48 olen++;
50 olen++;
51 }
49 olen += len / 4 * 5;
52 olen += len / 4 * 5;
50 }
53 }
51 if (!(out = PyBytes_FromStringAndSize(NULL, olen + 3)))
54 if (!(out = PyBytes_FromStringAndSize(NULL, olen + 3))) {
52 return NULL;
55 return NULL;
56 }
53
57
54 dst = PyBytes_AsString(out);
58 dst = PyBytes_AsString(out);
55
59
@@ -58,8 +62,9 b' static PyObject *b85encode(PyObject *sel'
58 for (i = 24; i >= 0; i -= 8) {
62 for (i = 24; i >= 0; i -= 8) {
59 ch = *text++;
63 ch = *text++;
60 acc |= ch << i;
64 acc |= ch << i;
61 if (--len == 0)
65 if (--len == 0) {
62 break;
66 break;
67 }
63 }
68 }
64 for (i = 4; i >= 0; i--) {
69 for (i = 4; i >= 0; i--) {
65 val = acc % 85;
70 val = acc % 85;
@@ -69,8 +74,9 b' static PyObject *b85encode(PyObject *sel'
69 dst += 5;
74 dst += 5;
70 }
75 }
71
76
72 if (!pad)
77 if (!pad) {
73 _PyBytes_Resize(&out, olen);
78 _PyBytes_Resize(&out, olen);
79 }
74
80
75 return out;
81 return out;
76 }
82 }
@@ -84,15 +90,18 b' static PyObject *b85decode(PyObject *sel'
84 int c;
90 int c;
85 unsigned int acc;
91 unsigned int acc;
86
92
87 if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &text, &len))
93 if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &text, &len)) {
88 return NULL;
94 return NULL;
95 }
89
96
90 olen = len / 5 * 4;
97 olen = len / 5 * 4;
91 i = len % 5;
98 i = len % 5;
92 if (i)
99 if (i) {
93 olen += i - 1;
100 olen += i - 1;
94 if (!(out = PyBytes_FromStringAndSize(NULL, olen)))
101 }
102 if (!(out = PyBytes_FromStringAndSize(NULL, olen))) {
95 return NULL;
103 return NULL;
104 }
96
105
97 dst = PyBytes_AsString(out);
106 dst = PyBytes_AsString(out);
98
107
@@ -100,8 +109,9 b' static PyObject *b85decode(PyObject *sel'
100 while (i < len) {
109 while (i < len) {
101 acc = 0;
110 acc = 0;
102 cap = len - i - 1;
111 cap = len - i - 1;
103 if (cap > 4)
112 if (cap > 4) {
104 cap = 4;
113 cap = 4;
114 }
105 for (j = 0; j < cap; i++, j++) {
115 for (j = 0; j < cap; i++, j++) {
106 c = b85dec[(int)*text++] - 1;
116 c = b85dec[(int)*text++] - 1;
107 if (c < 0) {
117 if (c < 0) {
@@ -136,10 +146,12 b' static PyObject *b85decode(PyObject *sel'
136
146
137 cap = olen < 4 ? olen : 4;
147 cap = olen < 4 ? olen : 4;
138 olen -= cap;
148 olen -= cap;
139 for (j = 0; j < 4 - cap; j++)
149 for (j = 0; j < 4 - cap; j++) {
140 acc *= 85;
150 acc *= 85;
141 if (cap && cap < 4)
151 }
152 if (cap && cap < 4) {
142 acc += 0xffffff >> (cap - 1) * 8;
153 acc += 0xffffff >> (cap - 1) * 8;
154 }
143 for (j = 0; j < cap; j++) {
155 for (j = 0; j < cap; j++) {
144 acc = (acc << 8) | (acc >> 24);
156 acc = (acc << 8) | (acc >> 24);
145 *dst++ = acc;
157 *dst++ = acc;
@@ -29,22 +29,26 b' static PyObject *blocks(PyObject *self, '
29
29
30 l.next = NULL;
30 l.next = NULL;
31
31
32 if (!PyArg_ParseTuple(args, "SS:bdiff", &sa, &sb))
32 if (!PyArg_ParseTuple(args, "SS:bdiff", &sa, &sb)) {
33 return NULL;
33 return NULL;
34 }
34
35
35 an = bdiff_splitlines(PyBytes_AsString(sa), PyBytes_Size(sa), &a);
36 an = bdiff_splitlines(PyBytes_AsString(sa), PyBytes_Size(sa), &a);
36 bn = bdiff_splitlines(PyBytes_AsString(sb), PyBytes_Size(sb), &b);
37 bn = bdiff_splitlines(PyBytes_AsString(sb), PyBytes_Size(sb), &b);
37
38
38 if (!a || !b)
39 if (!a || !b) {
39 goto nomem;
40 goto nomem;
41 }
40
42
41 count = bdiff_diff(a, an, b, bn, &l);
43 count = bdiff_diff(a, an, b, bn, &l);
42 if (count < 0)
44 if (count < 0) {
43 goto nomem;
45 goto nomem;
46 }
44
47
45 rl = PyList_New(count);
48 rl = PyList_New(count);
46 if (!rl)
49 if (!rl) {
47 goto nomem;
50 goto nomem;
51 }
48
52
49 for (h = l.next; h; h = h->next) {
53 for (h = l.next; h; h = h->next) {
50 m = Py_BuildValue("iiii", h->a1, h->a2, h->b1, h->b2);
54 m = Py_BuildValue("iiii", h->a1, h->a2, h->b1, h->b2);
@@ -72,8 +76,10 b' static PyObject *bdiff(PyObject *self, P'
72
76
73 l.next = NULL;
77 l.next = NULL;
74
78
75 if (!PyArg_ParseTuple(args, PY23("s*s*:bdiff", "y*y*:bdiff"), &ba, &bb))
79 if (!PyArg_ParseTuple(args, PY23("s*s*:bdiff", "y*y*:bdiff"), &ba,
80 &bb)) {
76 return NULL;
81 return NULL;
82 }
77
83
78 if (!PyBuffer_IsContiguous(&ba, 'C') || ba.ndim > 1) {
84 if (!PyBuffer_IsContiguous(&ba, 'C') || ba.ndim > 1) {
79 PyErr_SetString(PyExc_ValueError, "bdiff input not contiguous");
85 PyErr_SetString(PyExc_ValueError, "bdiff input not contiguous");
@@ -98,8 +104,9 b' static PyObject *bdiff(PyObject *self, P'
98 lmax = la > lb ? lb : la;
104 lmax = la > lb ? lb : la;
99 for (ia = ba.buf, ib = bb.buf; li < lmax && *ia == *ib;
105 for (ia = ba.buf, ib = bb.buf; li < lmax && *ia == *ib;
100 ++li, ++ia, ++ib) {
106 ++li, ++ia, ++ib) {
101 if (*ia == '\n')
107 if (*ia == '\n') {
102 lcommon = li + 1;
108 lcommon = li + 1;
109 }
103 }
110 }
104 /* we can almost add: if (li == lmax) lcommon = li; */
111 /* we can almost add: if (li == lmax) lcommon = li; */
105
112
@@ -119,8 +126,9 b' static PyObject *bdiff(PyObject *self, P'
119 /* calculate length of output */
126 /* calculate length of output */
120 la = lb = 0;
127 la = lb = 0;
121 for (h = l.next; h; h = h->next) {
128 for (h = l.next; h; h = h->next) {
122 if (h->a1 != la || h->b1 != lb)
129 if (h->a1 != la || h->b1 != lb) {
123 len += 12 + bl[h->b1].l - bl[lb].l;
130 len += 12 + bl[h->b1].l - bl[lb].l;
131 }
124 la = h->a2;
132 la = h->a2;
125 lb = h->b2;
133 lb = h->b2;
126 }
134 }
@@ -129,8 +137,9 b' static PyObject *bdiff(PyObject *self, P'
129
137
130 result = PyBytes_FromStringAndSize(NULL, len);
138 result = PyBytes_FromStringAndSize(NULL, len);
131
139
132 if (!result)
140 if (!result) {
133 goto cleanup;
141 goto cleanup;
142 }
134
143
135 /* build binary patch */
144 /* build binary patch */
136 rb = PyBytes_AsString(result);
145 rb = PyBytes_AsString(result);
@@ -151,8 +160,9 b' static PyObject *bdiff(PyObject *self, P'
151 }
160 }
152
161
153 cleanup:
162 cleanup:
154 if (_save)
163 if (_save) {
155 PyEval_RestoreThread(_save);
164 PyEval_RestoreThread(_save);
165 }
156 PyBuffer_Release(&ba);
166 PyBuffer_Release(&ba);
157 PyBuffer_Release(&bb);
167 PyBuffer_Release(&bb);
158 free(al);
168 free(al);
@@ -174,20 +184,23 b' static PyObject *fixws(PyObject *self, P'
174 Py_ssize_t i, rlen, wlen = 0;
184 Py_ssize_t i, rlen, wlen = 0;
175 char *w;
185 char *w;
176
186
177 if (!PyArg_ParseTuple(args, "Sb:fixws", &s, &allws))
187 if (!PyArg_ParseTuple(args, "Sb:fixws", &s, &allws)) {
178 return NULL;
188 return NULL;
189 }
179 r = PyBytes_AsString(s);
190 r = PyBytes_AsString(s);
180 rlen = PyBytes_Size(s);
191 rlen = PyBytes_Size(s);
181
192
182 w = (char *)PyMem_Malloc(rlen ? rlen : 1);
193 w = (char *)PyMem_Malloc(rlen ? rlen : 1);
183 if (!w)
194 if (!w) {
184 goto nomem;
195 goto nomem;
196 }
185
197
186 for (i = 0; i != rlen; i++) {
198 for (i = 0; i != rlen; i++) {
187 c = r[i];
199 c = r[i];
188 if (c == ' ' || c == '\t' || c == '\r') {
200 if (c == ' ' || c == '\t' || c == '\r') {
189 if (!allws && (wlen == 0 || w[wlen - 1] != ' '))
201 if (!allws && (wlen == 0 || w[wlen - 1] != ' ')) {
190 w[wlen++] = ' ';
202 w[wlen++] = ' ';
203 }
191 } else if (c == '\n' && !allws && wlen > 0 &&
204 } else if (c == '\n' && !allws && wlen > 0 &&
192 w[wlen - 1] == ' ') {
205 w[wlen - 1] == ' ') {
193 w[wlen - 1] = '\n';
206 w[wlen - 1] = '\n';
@@ -207,8 +220,9 b' static bool sliceintolist(PyObject *list'
207 const char *source, Py_ssize_t len)
220 const char *source, Py_ssize_t len)
208 {
221 {
209 PyObject *sliced = PyBytes_FromStringAndSize(source, len);
222 PyObject *sliced = PyBytes_FromStringAndSize(source, len);
210 if (sliced == NULL)
223 if (sliced == NULL) {
211 return false;
224 return false;
225 }
212 PyList_SET_ITEM(list, destidx, sliced);
226 PyList_SET_ITEM(list, destidx, sliced);
213 return true;
227 return true;
214 }
228 }
@@ -232,19 +246,22 b' static PyObject *splitnewlines(PyObject '
232 ++nelts;
246 ++nelts;
233 }
247 }
234 }
248 }
235 if ((result = PyList_New(nelts + 1)) == NULL)
249 if ((result = PyList_New(nelts + 1)) == NULL) {
236 goto abort;
250 goto abort;
251 }
237 nelts = 0;
252 nelts = 0;
238 for (i = 0; i < size - 1; ++i) {
253 for (i = 0; i < size - 1; ++i) {
239 if (text[i] == '\n') {
254 if (text[i] == '\n') {
240 if (!sliceintolist(result, nelts++, text + start,
255 if (!sliceintolist(result, nelts++, text + start,
241 i - start + 1))
256 i - start + 1)) {
242 goto abort;
257 goto abort;
258 }
243 start = i + 1;
259 start = i + 1;
244 }
260 }
245 }
261 }
246 if (!sliceintolist(result, nelts++, text + start, size - start))
262 if (!sliceintolist(result, nelts++, text + start, size - start)) {
247 goto abort;
263 goto abort;
264 }
248 return result;
265 return result;
249 abort:
266 abort:
250 Py_XDECREF(result);
267 Py_XDECREF(result);
@@ -257,8 +274,9 b' static int hunk_consumer(int64_t a1, int'
257 PyObject *rl = (PyObject *)priv;
274 PyObject *rl = (PyObject *)priv;
258 PyObject *m = Py_BuildValue("LLLL", a1, a2, b1, b2);
275 PyObject *m = Py_BuildValue("LLLL", a1, a2, b1, b2);
259 int r;
276 int r;
260 if (!m)
277 if (!m) {
261 return -1;
278 return -1;
279 }
262 r = PyList_Append(rl, m);
280 r = PyList_Append(rl, m);
263 Py_DECREF(m);
281 Py_DECREF(m);
264 return r;
282 return r;
@@ -282,15 +300,17 b' static PyObject *xdiffblocks(PyObject *s'
282 };
300 };
283
301
284 if (!PyArg_ParseTuple(args, PY23("s#s#", "y#y#"), &a.ptr, &la, &b.ptr,
302 if (!PyArg_ParseTuple(args, PY23("s#s#", "y#y#"), &a.ptr, &la, &b.ptr,
285 &lb))
303 &lb)) {
286 return NULL;
304 return NULL;
305 }
287
306
288 a.size = la;
307 a.size = la;
289 b.size = lb;
308 b.size = lb;
290
309
291 rl = PyList_New(0);
310 rl = PyList_New(0);
292 if (!rl)
311 if (!rl) {
293 return PyErr_NoMemory();
312 return PyErr_NoMemory();
313 }
294
314
295 ecb.priv = rl;
315 ecb.priv = rl;
296
316
@@ -114,8 +114,9 b' PyObject *unhexlify(const char *str, Py_'
114
114
115 ret = PyBytes_FromStringAndSize(NULL, len / 2);
115 ret = PyBytes_FromStringAndSize(NULL, len / 2);
116
116
117 if (!ret)
117 if (!ret) {
118 return NULL;
118 return NULL;
119 }
119
120
120 d = PyBytes_AsString(ret);
121 d = PyBytes_AsString(ret);
121
122
@@ -133,21 +134,24 b' PyObject *isasciistr(PyObject *self, PyO'
133 const char *buf;
134 const char *buf;
134 Py_ssize_t i, len;
135 Py_ssize_t i, len;
135 if (!PyArg_ParseTuple(args, PY23("s#:isasciistr", "y#:isasciistr"),
136 if (!PyArg_ParseTuple(args, PY23("s#:isasciistr", "y#:isasciistr"),
136 &buf, &len))
137 &buf, &len)) {
137 return NULL;
138 return NULL;
139 }
138 i = 0;
140 i = 0;
139 /* char array in PyStringObject should be at least 4-byte aligned */
141 /* char array in PyStringObject should be at least 4-byte aligned */
140 if (((uintptr_t)buf & 3) == 0) {
142 if (((uintptr_t)buf & 3) == 0) {
141 const uint32_t *p = (const uint32_t *)buf;
143 const uint32_t *p = (const uint32_t *)buf;
142 for (; i < len / 4; i++) {
144 for (; i < len / 4; i++) {
143 if (p[i] & 0x80808080U)
145 if (p[i] & 0x80808080U) {
144 Py_RETURN_FALSE;
146 Py_RETURN_FALSE;
147 }
145 }
148 }
146 i *= 4;
149 i *= 4;
147 }
150 }
148 for (; i < len; i++) {
151 for (; i < len; i++) {
149 if (buf[i] & 0x80)
152 if (buf[i] & 0x80) {
150 Py_RETURN_FALSE;
153 Py_RETURN_FALSE;
154 }
151 }
155 }
152 Py_RETURN_TRUE;
156 Py_RETURN_TRUE;
153 }
157 }
@@ -164,8 +168,9 b' static inline PyObject *'
164 len = PyBytes_GET_SIZE(str_obj);
168 len = PyBytes_GET_SIZE(str_obj);
165
169
166 newobj = PyBytes_FromStringAndSize(NULL, len);
170 newobj = PyBytes_FromStringAndSize(NULL, len);
167 if (!newobj)
171 if (!newobj) {
168 goto quit;
172 goto quit;
173 }
169
174
170 newstr = PyBytes_AS_STRING(newobj);
175 newstr = PyBytes_AS_STRING(newobj);
171
176
@@ -197,16 +202,18 b' quit:'
197 PyObject *asciilower(PyObject *self, PyObject *args)
202 PyObject *asciilower(PyObject *self, PyObject *args)
198 {
203 {
199 PyObject *str_obj;
204 PyObject *str_obj;
200 if (!PyArg_ParseTuple(args, "O!:asciilower", &PyBytes_Type, &str_obj))
205 if (!PyArg_ParseTuple(args, "O!:asciilower", &PyBytes_Type, &str_obj)) {
201 return NULL;
206 return NULL;
207 }
202 return _asciitransform(str_obj, lowertable, NULL);
208 return _asciitransform(str_obj, lowertable, NULL);
203 }
209 }
204
210
205 PyObject *asciiupper(PyObject *self, PyObject *args)
211 PyObject *asciiupper(PyObject *self, PyObject *args)
206 {
212 {
207 PyObject *str_obj;
213 PyObject *str_obj;
208 if (!PyArg_ParseTuple(args, "O!:asciiupper", &PyBytes_Type, &str_obj))
214 if (!PyArg_ParseTuple(args, "O!:asciiupper", &PyBytes_Type, &str_obj)) {
209 return NULL;
215 return NULL;
216 }
210 return _asciitransform(str_obj, uppertable, NULL);
217 return _asciitransform(str_obj, uppertable, NULL);
211 }
218 }
212
219
@@ -222,8 +229,9 b' PyObject *make_file_foldmap(PyObject *se'
222
229
223 if (!PyArg_ParseTuple(args, "O!O!O!:make_file_foldmap", &PyDict_Type,
230 if (!PyArg_ParseTuple(args, "O!O!O!:make_file_foldmap", &PyDict_Type,
224 &dmap, &PyInt_Type, &spec_obj, &PyFunction_Type,
231 &dmap, &PyInt_Type, &spec_obj, &PyFunction_Type,
225 &normcase_fallback))
232 &normcase_fallback)) {
226 goto quit;
233 goto quit;
234 }
227
235
228 spec = (int)PyInt_AS_LONG(spec_obj);
236 spec = (int)PyInt_AS_LONG(spec_obj);
229 switch (spec) {
237 switch (spec) {
@@ -244,8 +252,9 b' PyObject *make_file_foldmap(PyObject *se'
244 /* Add some more entries to deal with additions outside this
252 /* Add some more entries to deal with additions outside this
245 function. */
253 function. */
246 file_foldmap = _dict_new_presized((PyDict_Size(dmap) / 10) * 11);
254 file_foldmap = _dict_new_presized((PyDict_Size(dmap) / 10) * 11);
247 if (file_foldmap == NULL)
255 if (file_foldmap == NULL) {
248 goto quit;
256 goto quit;
257 }
249
258
250 while (PyDict_Next(dmap, &pos, &k, &v)) {
259 while (PyDict_Next(dmap, &pos, &k, &v)) {
251 if (!dirstate_tuple_check(v)) {
260 if (!dirstate_tuple_check(v)) {
@@ -265,8 +274,9 b' PyObject *make_file_foldmap(PyObject *se'
265 normcase_fallback, k, NULL);
274 normcase_fallback, k, NULL);
266 }
275 }
267
276
268 if (normed == NULL)
277 if (normed == NULL) {
269 goto quit;
278 goto quit;
279 }
270 if (PyDict_SetItem(file_foldmap, normed, k) == -1) {
280 if (PyDict_SetItem(file_foldmap, normed, k) == -1) {
271 Py_DECREF(normed);
281 Py_DECREF(normed);
272 goto quit;
282 goto quit;
@@ -377,22 +387,25 b' PyObject *jsonescapeu8fast(PyObject *sel'
377 Py_ssize_t origlen, esclen;
387 Py_ssize_t origlen, esclen;
378 int paranoid;
388 int paranoid;
379 if (!PyArg_ParseTuple(args, "O!i:jsonescapeu8fast", &PyBytes_Type,
389 if (!PyArg_ParseTuple(args, "O!i:jsonescapeu8fast", &PyBytes_Type,
380 &origstr, &paranoid))
390 &origstr, &paranoid)) {
381 return NULL;
391 return NULL;
392 }
382
393
383 origbuf = PyBytes_AS_STRING(origstr);
394 origbuf = PyBytes_AS_STRING(origstr);
384 origlen = PyBytes_GET_SIZE(origstr);
395 origlen = PyBytes_GET_SIZE(origstr);
385 esclen = jsonescapelen(origbuf, origlen, paranoid);
396 esclen = jsonescapelen(origbuf, origlen, paranoid);
386 if (esclen < 0)
397 if (esclen < 0) {
387 return NULL; /* unsupported char found or overflow */
398 return NULL; /* unsupported char found or overflow */
399 }
388 if (origlen == esclen) {
400 if (origlen == esclen) {
389 Py_INCREF(origstr);
401 Py_INCREF(origstr);
390 return origstr;
402 return origstr;
391 }
403 }
392
404
393 escstr = PyBytes_FromStringAndSize(NULL, esclen);
405 escstr = PyBytes_FromStringAndSize(NULL, esclen);
394 if (!escstr)
406 if (!escstr) {
395 return NULL;
407 return NULL;
408 }
396 encodejsonescape(PyBytes_AS_STRING(escstr), esclen, origbuf, origlen,
409 encodejsonescape(PyBytes_AS_STRING(escstr), esclen, origbuf, origlen,
397 paranoid);
410 paranoid);
398
411
@@ -55,13 +55,16 b' struct mpatch_flist *cpygetitem(void *bi'
55 int r;
55 int r;
56
56
57 PyObject *tmp = PyList_GetItem((PyObject *)bins, pos);
57 PyObject *tmp = PyList_GetItem((PyObject *)bins, pos);
58 if (!tmp)
58 if (!tmp) {
59 return NULL;
59 return NULL;
60 if (PyObject_GetBuffer(tmp, &buffer, PyBUF_CONTIG_RO))
60 }
61 if (PyObject_GetBuffer(tmp, &buffer, PyBUF_CONTIG_RO)) {
61 return NULL;
62 return NULL;
63 }
62 if ((r = mpatch_decode(buffer.buf, buffer.len, &res)) < 0) {
64 if ((r = mpatch_decode(buffer.buf, buffer.len, &res)) < 0) {
63 if (!PyErr_Occurred())
65 if (!PyErr_Occurred()) {
64 setpyerr(r);
66 setpyerr(r);
67 }
65 res = NULL;
68 res = NULL;
66 }
69 }
67
70
@@ -78,8 +81,9 b' static PyObject *patches(PyObject *self,'
78 char *out;
81 char *out;
79 Py_ssize_t len, outlen;
82 Py_ssize_t len, outlen;
80
83
81 if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins))
84 if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins)) {
82 return NULL;
85 return NULL;
86 }
83
87
84 len = PyList_Size(bins);
88 len = PyList_Size(bins);
85 if (!len) {
89 if (!len) {
@@ -94,8 +98,9 b' static PyObject *patches(PyObject *self,'
94
98
95 patch = mpatch_fold(bins, cpygetitem, 0, len);
99 patch = mpatch_fold(bins, cpygetitem, 0, len);
96 if (!patch) { /* error already set or memory error */
100 if (!patch) { /* error already set or memory error */
97 if (!PyErr_Occurred())
101 if (!PyErr_Occurred()) {
98 PyErr_NoMemory();
102 PyErr_NoMemory();
103 }
99 result = NULL;
104 result = NULL;
100 goto cleanup;
105 goto cleanup;
101 }
106 }
@@ -126,8 +131,9 b' static PyObject *patches(PyObject *self,'
126 cleanup:
131 cleanup:
127 mpatch_lfree(patch);
132 mpatch_lfree(patch);
128 PyBuffer_Release(&buffer);
133 PyBuffer_Release(&buffer);
129 if (!result && !PyErr_Occurred())
134 if (!result && !PyErr_Occurred()) {
130 setpyerr(r);
135 setpyerr(r);
136 }
131 return result;
137 return result;
132 }
138 }
133
139
@@ -138,15 +144,18 b' static PyObject *patchedsize(PyObject *s'
138 Py_ssize_t patchlen;
144 Py_ssize_t patchlen;
139 char *bin;
145 char *bin;
140
146
141 if (!PyArg_ParseTuple(args, PY23("ls#", "ly#"), &orig, &bin, &patchlen))
147 if (!PyArg_ParseTuple(args, PY23("ls#", "ly#"), &orig, &bin,
148 &patchlen)) {
142 return NULL;
149 return NULL;
150 }
143
151
144 while (pos >= 0 && pos < patchlen) {
152 while (pos >= 0 && pos < patchlen) {
145 start = getbe32(bin + pos);
153 start = getbe32(bin + pos);
146 end = getbe32(bin + pos + 4);
154 end = getbe32(bin + pos + 4);
147 len = getbe32(bin + pos + 8);
155 len = getbe32(bin + pos + 8);
148 if (start > end)
156 if (start > end) {
149 break; /* sanity check */
157 break; /* sanity check */
158 }
150 pos += 12 + len;
159 pos += 12 + len;
151 outlen += start - last;
160 outlen += start - last;
152 last = end;
161 last = end;
@@ -154,9 +163,10 b' static PyObject *patchedsize(PyObject *s'
154 }
163 }
155
164
156 if (pos != patchlen) {
165 if (pos != patchlen) {
157 if (!PyErr_Occurred())
166 if (!PyErr_Occurred()) {
158 PyErr_SetString(mpatch_Error,
167 PyErr_SetString(mpatch_Error,
159 "patch cannot be decoded");
168 "patch cannot be decoded");
169 }
160 return NULL;
170 return NULL;
161 }
171 }
162
172
@@ -32,8 +32,9 b' static PyObject *dict_new_presized(PyObj'
32 {
32 {
33 Py_ssize_t expected_size;
33 Py_ssize_t expected_size;
34
34
35 if (!PyArg_ParseTuple(args, "n:make_presized_dict", &expected_size))
35 if (!PyArg_ParseTuple(args, "n:make_presized_dict", &expected_size)) {
36 return NULL;
36 return NULL;
37 }
37
38
38 return _dict_new_presized(expected_size);
39 return _dict_new_presized(expected_size);
39 }
40 }
@@ -43,8 +44,9 b' static inline dirstateTupleObject *make_'
43 {
44 {
44 dirstateTupleObject *t =
45 dirstateTupleObject *t =
45 PyObject_New(dirstateTupleObject, &dirstateTupleType);
46 PyObject_New(dirstateTupleObject, &dirstateTupleType);
46 if (!t)
47 if (!t) {
47 return NULL;
48 return NULL;
49 }
48 t->state = state;
50 t->state = state;
49 t->mode = mode;
51 t->mode = mode;
50 t->size = size;
52 t->size = size;
@@ -60,12 +62,14 b' static PyObject *dirstate_tuple_new(PyTy'
60 dirstateTupleObject *t;
62 dirstateTupleObject *t;
61 char state;
63 char state;
62 int size, mode, mtime;
64 int size, mode, mtime;
63 if (!PyArg_ParseTuple(args, "ciii", &state, &mode, &size, &mtime))
65 if (!PyArg_ParseTuple(args, "ciii", &state, &mode, &size, &mtime)) {
64 return NULL;
66 return NULL;
67 }
65
68
66 t = (dirstateTupleObject *)subtype->tp_alloc(subtype, 1);
69 t = (dirstateTupleObject *)subtype->tp_alloc(subtype, 1);
67 if (!t)
70 if (!t) {
68 return NULL;
71 return NULL;
72 }
69 t->state = state;
73 t->state = state;
70 t->mode = mode;
74 t->mode = mode;
71 t->size = size;
75 t->size = size;
@@ -165,8 +169,9 b' static PyObject *parse_dirstate(PyObject'
165
169
166 if (!PyArg_ParseTuple(
170 if (!PyArg_ParseTuple(
167 args, PY23("O!O!s#:parse_dirstate", "O!O!y#:parse_dirstate"),
171 args, PY23("O!O!s#:parse_dirstate", "O!O!y#:parse_dirstate"),
168 &PyDict_Type, &dmap, &PyDict_Type, &cmap, &str, &readlen))
172 &PyDict_Type, &dmap, &PyDict_Type, &cmap, &str, &readlen)) {
169 goto quit;
173 goto quit;
174 }
170
175
171 len = readlen;
176 len = readlen;
172
177
@@ -178,8 +183,9 b' static PyObject *parse_dirstate(PyObject'
178 }
183 }
179
184
180 parents = Py_BuildValue(PY23("s#s#", "y#y#"), str, 20, str + 20, 20);
185 parents = Py_BuildValue(PY23("s#s#", "y#y#"), str, 20, str + 20, 20);
181 if (!parents)
186 if (!parents) {
182 goto quit;
187 goto quit;
188 }
183
189
184 /* read filenames */
190 /* read filenames */
185 while (pos >= 40 && pos < len) {
191 while (pos >= 40 && pos < len) {
@@ -212,13 +218,16 b' static PyObject *parse_dirstate(PyObject'
212 cpos + 1, flen - (cpos - cur) - 1);
218 cpos + 1, flen - (cpos - cur) - 1);
213 if (!fname || !cname ||
219 if (!fname || !cname ||
214 PyDict_SetItem(cmap, fname, cname) == -1 ||
220 PyDict_SetItem(cmap, fname, cname) == -1 ||
215 PyDict_SetItem(dmap, fname, entry) == -1)
221 PyDict_SetItem(dmap, fname, entry) == -1) {
216 goto quit;
222 goto quit;
223 }
217 Py_DECREF(cname);
224 Py_DECREF(cname);
218 } else {
225 } else {
219 fname = PyBytes_FromStringAndSize(cur, flen);
226 fname = PyBytes_FromStringAndSize(cur, flen);
220 if (!fname || PyDict_SetItem(dmap, fname, entry) == -1)
227 if (!fname ||
228 PyDict_SetItem(dmap, fname, entry) == -1) {
221 goto quit;
229 goto quit;
230 }
222 }
231 }
223 Py_DECREF(fname);
232 Py_DECREF(fname);
224 Py_DECREF(entry);
233 Py_DECREF(entry);
@@ -245,16 +254,20 b' static PyObject *nonnormalotherparentent'
245 PyObject *nonnset = NULL, *otherpset = NULL, *result = NULL;
254 PyObject *nonnset = NULL, *otherpset = NULL, *result = NULL;
246 Py_ssize_t pos;
255 Py_ssize_t pos;
247
256
248 if (!PyArg_ParseTuple(args, "O!:nonnormalentries", &PyDict_Type, &dmap))
257 if (!PyArg_ParseTuple(args, "O!:nonnormalentries", &PyDict_Type,
258 &dmap)) {
249 goto bail;
259 goto bail;
260 }
250
261
251 nonnset = PySet_New(NULL);
262 nonnset = PySet_New(NULL);
252 if (nonnset == NULL)
263 if (nonnset == NULL) {
253 goto bail;
264 goto bail;
265 }
254
266
255 otherpset = PySet_New(NULL);
267 otherpset = PySet_New(NULL);
256 if (otherpset == NULL)
268 if (otherpset == NULL) {
257 goto bail;
269 goto bail;
270 }
258
271
259 pos = 0;
272 pos = 0;
260 while (PyDict_Next(dmap, &pos, &fname, &v)) {
273 while (PyDict_Next(dmap, &pos, &fname, &v)) {
@@ -272,15 +285,18 b' static PyObject *nonnormalotherparentent'
272 }
285 }
273 }
286 }
274
287
275 if (t->state == 'n' && t->mtime != -1)
288 if (t->state == 'n' && t->mtime != -1) {
276 continue;
289 continue;
277 if (PySet_Add(nonnset, fname) == -1)
290 }
291 if (PySet_Add(nonnset, fname) == -1) {
278 goto bail;
292 goto bail;
293 }
279 }
294 }
280
295
281 result = Py_BuildValue("(OO)", nonnset, otherpset);
296 result = Py_BuildValue("(OO)", nonnset, otherpset);
282 if (result == NULL)
297 if (result == NULL) {
283 goto bail;
298 goto bail;
299 }
284 Py_DECREF(nonnset);
300 Py_DECREF(nonnset);
285 Py_DECREF(otherpset);
301 Py_DECREF(otherpset);
286 return result;
302 return result;
@@ -304,8 +320,10 b' static PyObject *pack_dirstate(PyObject '
304 int now;
320 int now;
305
321
306 if (!PyArg_ParseTuple(args, "O!O!O!i:pack_dirstate", &PyDict_Type, &map,
322 if (!PyArg_ParseTuple(args, "O!O!O!i:pack_dirstate", &PyDict_Type, &map,
307 &PyDict_Type, &copymap, &PyTuple_Type, &pl, &now))
323 &PyDict_Type, &copymap, &PyTuple_Type, &pl,
324 &now)) {
308 return NULL;
325 return NULL;
326 }
309
327
310 if (PyTuple_Size(pl) != 2) {
328 if (PyTuple_Size(pl) != 2) {
311 PyErr_SetString(PyExc_TypeError, "expected 2-element tuple");
329 PyErr_SetString(PyExc_TypeError, "expected 2-element tuple");
@@ -332,8 +350,9 b' static PyObject *pack_dirstate(PyObject '
332 }
350 }
333
351
334 packobj = PyBytes_FromStringAndSize(NULL, nbytes);
352 packobj = PyBytes_FromStringAndSize(NULL, nbytes);
335 if (packobj == NULL)
353 if (packobj == NULL) {
336 goto bail;
354 goto bail;
355 }
337
356
338 p = PyBytes_AS_STRING(packobj);
357 p = PyBytes_AS_STRING(packobj);
339
358
@@ -377,10 +396,12 b' static PyObject *pack_dirstate(PyObject '
377 mtime = -1;
396 mtime = -1;
378 mtime_unset = (PyObject *)make_dirstate_tuple(
397 mtime_unset = (PyObject *)make_dirstate_tuple(
379 state, mode, size, mtime);
398 state, mode, size, mtime);
380 if (!mtime_unset)
399 if (!mtime_unset) {
381 goto bail;
400 goto bail;
382 if (PyDict_SetItem(map, k, mtime_unset) == -1)
401 }
402 if (PyDict_SetItem(map, k, mtime_unset) == -1) {
383 goto bail;
403 goto bail;
404 }
384 Py_DECREF(mtime_unset);
405 Py_DECREF(mtime_unset);
385 mtime_unset = NULL;
406 mtime_unset = NULL;
386 }
407 }
@@ -664,8 +685,9 b' static void module_init(PyObject *mod)'
664 manifest_module_init(mod);
685 manifest_module_init(mod);
665 revlog_module_init(mod);
686 revlog_module_init(mod);
666
687
667 if (PyType_Ready(&dirstateTupleType) < 0)
688 if (PyType_Ready(&dirstateTupleType) < 0) {
668 return;
689 return;
690 }
669 Py_INCREF(&dirstateTupleType);
691 Py_INCREF(&dirstateTupleType);
670 PyModule_AddObject(mod, "dirstatetuple",
692 PyModule_AddObject(mod, "dirstatetuple",
671 (PyObject *)&dirstateTupleType);
693 (PyObject *)&dirstateTupleType);
@@ -675,12 +697,14 b' static int check_python_version(void)'
675 {
697 {
676 PyObject *sys = PyImport_ImportModule("sys"), *ver;
698 PyObject *sys = PyImport_ImportModule("sys"), *ver;
677 long hexversion;
699 long hexversion;
678 if (!sys)
700 if (!sys) {
679 return -1;
701 return -1;
702 }
680 ver = PyObject_GetAttrString(sys, "hexversion");
703 ver = PyObject_GetAttrString(sys, "hexversion");
681 Py_DECREF(sys);
704 Py_DECREF(sys);
682 if (!ver)
705 if (!ver) {
683 return -1;
706 return -1;
707 }
684 hexversion = PyInt_AsLong(ver);
708 hexversion = PyInt_AsLong(ver);
685 Py_DECREF(ver);
709 Py_DECREF(ver);
686 /* sys.hexversion is a 32-bit number by default, so the -1 case
710 /* sys.hexversion is a 32-bit number by default, so the -1 case
@@ -720,8 +744,9 b' PyMODINIT_FUNC initparsers(void)'
720 {
744 {
721 PyObject *mod;
745 PyObject *mod;
722
746
723 if (check_python_version() == -1)
747 if (check_python_version() == -1) {
724 return;
748 return;
749 }
725 mod = Py_InitModule3("parsers", methods, parsers_doc);
750 mod = Py_InitModule3("parsers", methods, parsers_doc);
726 module_init(mod);
751 module_init(mod);
727 }
752 }
@@ -126,8 +126,9 b' static Py_ssize_t _encodedir(char *dest,'
126 if (src[i] == 'g') {
126 if (src[i] == 'g') {
127 state = DHGDI;
127 state = DHGDI;
128 charcopy(dest, &destlen, destsize, src[i++]);
128 charcopy(dest, &destlen, destsize, src[i++]);
129 } else
129 } else {
130 state = DDEFAULT;
130 state = DDEFAULT;
131 }
131 break;
132 break;
132 case DHGDI:
133 case DHGDI:
133 if (src[i] == '/') {
134 if (src[i] == '/') {
@@ -137,8 +138,9 b' static Py_ssize_t _encodedir(char *dest,'
137 state = DDEFAULT;
138 state = DDEFAULT;
138 break;
139 break;
139 case DDEFAULT:
140 case DDEFAULT:
140 if (src[i] == '.')
141 if (src[i] == '.') {
141 state = DDOT;
142 state = DDOT;
143 }
142 charcopy(dest, &destlen, destsize, src[i++]);
144 charcopy(dest, &destlen, destsize, src[i++]);
143 break;
145 break;
144 }
146 }
@@ -153,8 +155,9 b' PyObject *encodedir(PyObject *self, PyOb'
153 PyObject *pathobj, *newobj;
155 PyObject *pathobj, *newobj;
154 char *path;
156 char *path;
155
157
156 if (!PyArg_ParseTuple(args, "O:encodedir", &pathobj))
158 if (!PyArg_ParseTuple(args, "O:encodedir", &pathobj)) {
157 return NULL;
159 return NULL;
160 }
158
161
159 if (PyBytes_AsStringAndSize(pathobj, &path, &len) == -1) {
162 if (PyBytes_AsStringAndSize(pathobj, &path, &len) == -1) {
160 PyErr_SetString(PyExc_TypeError, "expected a string");
163 PyErr_SetString(PyExc_TypeError, "expected a string");
@@ -235,15 +238,17 b' static Py_ssize_t _encode(const uint32_t'
235 if (src[i] == 'u') {
238 if (src[i] == 'u') {
236 state = AU;
239 state = AU;
237 charcopy(dest, &destlen, destsize, src[i++]);
240 charcopy(dest, &destlen, destsize, src[i++]);
238 } else
241 } else {
239 state = DEFAULT;
242 state = DEFAULT;
243 }
240 break;
244 break;
241 case AU:
245 case AU:
242 if (src[i] == 'x') {
246 if (src[i] == 'x') {
243 state = THIRD;
247 state = THIRD;
244 i++;
248 i++;
245 } else
249 } else {
246 state = DEFAULT;
250 state = DEFAULT;
251 }
247 break;
252 break;
248 case THIRD:
253 case THIRD:
249 state = DEFAULT;
254 state = DEFAULT;
@@ -262,8 +267,9 b' static Py_ssize_t _encode(const uint32_t'
262 if (src[i] == 'o') {
267 if (src[i] == 'o') {
263 state = CO;
268 state = CO;
264 charcopy(dest, &destlen, destsize, src[i++]);
269 charcopy(dest, &destlen, destsize, src[i++]);
265 } else
270 } else {
266 state = DEFAULT;
271 state = DEFAULT;
272 }
267 break;
273 break;
268 case CO:
274 case CO:
269 if (src[i] == 'm') {
275 if (src[i] == 'm') {
@@ -272,8 +278,9 b' static Py_ssize_t _encode(const uint32_t'
272 } else if (src[i] == 'n') {
278 } else if (src[i] == 'n') {
273 state = THIRD;
279 state = THIRD;
274 i++;
280 i++;
275 } else
281 } else {
276 state = DEFAULT;
282 state = DEFAULT;
283 }
277 break;
284 break;
278 case COMLPT:
285 case COMLPT:
279 switch (src[i]) {
286 switch (src[i]) {
@@ -314,43 +321,49 b' static Py_ssize_t _encode(const uint32_t'
314 if (src[i] == 'p') {
321 if (src[i] == 'p') {
315 state = LP;
322 state = LP;
316 charcopy(dest, &destlen, destsize, src[i++]);
323 charcopy(dest, &destlen, destsize, src[i++]);
317 } else
324 } else {
318 state = DEFAULT;
325 state = DEFAULT;
326 }
319 break;
327 break;
320 case LP:
328 case LP:
321 if (src[i] == 't') {
329 if (src[i] == 't') {
322 state = COMLPT;
330 state = COMLPT;
323 i++;
331 i++;
324 } else
332 } else {
325 state = DEFAULT;
333 state = DEFAULT;
334 }
326 break;
335 break;
327 case N:
336 case N:
328 if (src[i] == 'u') {
337 if (src[i] == 'u') {
329 state = NU;
338 state = NU;
330 charcopy(dest, &destlen, destsize, src[i++]);
339 charcopy(dest, &destlen, destsize, src[i++]);
331 } else
340 } else {
332 state = DEFAULT;
341 state = DEFAULT;
342 }
333 break;
343 break;
334 case NU:
344 case NU:
335 if (src[i] == 'l') {
345 if (src[i] == 'l') {
336 state = THIRD;
346 state = THIRD;
337 i++;
347 i++;
338 } else
348 } else {
339 state = DEFAULT;
349 state = DEFAULT;
350 }
340 break;
351 break;
341 case P:
352 case P:
342 if (src[i] == 'r') {
353 if (src[i] == 'r') {
343 state = PR;
354 state = PR;
344 charcopy(dest, &destlen, destsize, src[i++]);
355 charcopy(dest, &destlen, destsize, src[i++]);
345 } else
356 } else {
346 state = DEFAULT;
357 state = DEFAULT;
358 }
347 break;
359 break;
348 case PR:
360 case PR:
349 if (src[i] == 'n') {
361 if (src[i] == 'n') {
350 state = THIRD;
362 state = THIRD;
351 i++;
363 i++;
352 } else
364 } else {
353 state = DEFAULT;
365 state = DEFAULT;
366 }
354 break;
367 break;
355 case LDOT:
368 case LDOT:
356 switch (src[i]) {
369 switch (src[i]) {
@@ -397,18 +410,21 b' static Py_ssize_t _encode(const uint32_t'
397 if (src[i] == 'g') {
410 if (src[i] == 'g') {
398 state = HGDI;
411 state = HGDI;
399 charcopy(dest, &destlen, destsize, src[i++]);
412 charcopy(dest, &destlen, destsize, src[i++]);
400 } else
413 } else {
401 state = DEFAULT;
414 state = DEFAULT;
415 }
402 break;
416 break;
403 case HGDI:
417 case HGDI:
404 if (src[i] == '/') {
418 if (src[i] == '/') {
405 state = START;
419 state = START;
406 if (encodedir)
420 if (encodedir) {
407 memcopy(dest, &destlen, destsize, ".hg",
421 memcopy(dest, &destlen, destsize, ".hg",
408 3);
422 3);
423 }
409 charcopy(dest, &destlen, destsize, src[i++]);
424 charcopy(dest, &destlen, destsize, src[i++]);
410 } else
425 } else {
411 state = DEFAULT;
426 state = DEFAULT;
427 }
412 break;
428 break;
413 case SPACE:
429 case SPACE:
414 switch (src[i]) {
430 switch (src[i]) {
@@ -427,8 +443,9 b' static Py_ssize_t _encode(const uint32_t'
427 case DEFAULT:
443 case DEFAULT:
428 while (inset(onebyte, src[i])) {
444 while (inset(onebyte, src[i])) {
429 charcopy(dest, &destlen, destsize, src[i++]);
445 charcopy(dest, &destlen, destsize, src[i++]);
430 if (i == len)
446 if (i == len) {
431 goto done;
447 goto done;
448 }
432 }
449 }
433 switch (src[i]) {
450 switch (src[i]) {
434 case '.':
451 case '.':
@@ -456,9 +473,10 b' static Py_ssize_t _encode(const uint32_t'
456 charcopy(dest, &destlen, destsize, '_');
473 charcopy(dest, &destlen, destsize, '_');
457 charcopy(dest, &destlen, destsize,
474 charcopy(dest, &destlen, destsize,
458 c == '_' ? '_' : c + 32);
475 c == '_' ? '_' : c + 32);
459 } else
476 } else {
460 escape3(dest, &destlen, destsize,
477 escape3(dest, &destlen, destsize,
461 src[i++]);
478 src[i++]);
479 }
462 break;
480 break;
463 }
481 }
464 break;
482 break;
@@ -498,12 +516,13 b' static Py_ssize_t _lowerencode(char *des'
498 Py_ssize_t i, destlen = 0;
516 Py_ssize_t i, destlen = 0;
499
517
500 for (i = 0; i < len; i++) {
518 for (i = 0; i < len; i++) {
501 if (inset(onebyte, src[i]))
519 if (inset(onebyte, src[i])) {
502 charcopy(dest, &destlen, destsize, src[i]);
520 charcopy(dest, &destlen, destsize, src[i]);
503 else if (inset(lower, src[i]))
521 } else if (inset(lower, src[i])) {
504 charcopy(dest, &destlen, destsize, src[i] + 32);
522 charcopy(dest, &destlen, destsize, src[i] + 32);
505 else
523 } else {
506 escape3(dest, &destlen, destsize, src[i]);
524 escape3(dest, &destlen, destsize, src[i]);
525 }
507 }
526 }
508
527
509 return destlen;
528 return destlen;
@@ -516,13 +535,15 b' PyObject *lowerencode(PyObject *self, Py'
516 PyObject *ret;
535 PyObject *ret;
517
536
518 if (!PyArg_ParseTuple(args, PY23("s#:lowerencode", "y#:lowerencode"),
537 if (!PyArg_ParseTuple(args, PY23("s#:lowerencode", "y#:lowerencode"),
519 &path, &len))
538 &path, &len)) {
520 return NULL;
539 return NULL;
540 }
521
541
522 newlen = _lowerencode(NULL, 0, path, len);
542 newlen = _lowerencode(NULL, 0, path, len);
523 ret = PyBytes_FromStringAndSize(NULL, newlen);
543 ret = PyBytes_FromStringAndSize(NULL, newlen);
524 if (ret)
544 if (ret) {
525 _lowerencode(PyBytes_AS_STRING(ret), newlen, path, len);
545 _lowerencode(PyBytes_AS_STRING(ret), newlen, path, len);
546 }
526
547
527 return ret;
548 return ret;
528 }
549 }
@@ -551,8 +572,9 b' static PyObject *hashmangle(const char *'
551 Py_ssize_t destsize, destlen = 0, slop, used;
572 Py_ssize_t destsize, destlen = 0, slop, used;
552
573
553 while (lastslash >= 0 && src[lastslash] != '/') {
574 while (lastslash >= 0 && src[lastslash] != '/') {
554 if (src[lastslash] == '.' && lastdot == -1)
575 if (src[lastslash] == '.' && lastdot == -1) {
555 lastdot = lastslash;
576 lastdot = lastslash;
577 }
556 lastslash--;
578 lastslash--;
557 }
579 }
558
580
@@ -570,12 +592,14 b' static PyObject *hashmangle(const char *'
570 /* If src contains a suffix, we will append it to the end of
592 /* If src contains a suffix, we will append it to the end of
571 the new string, so make room. */
593 the new string, so make room. */
572 destsize = 120;
594 destsize = 120;
573 if (lastdot >= 0)
595 if (lastdot >= 0) {
574 destsize += len - lastdot - 1;
596 destsize += len - lastdot - 1;
597 }
575
598
576 ret = PyBytes_FromStringAndSize(NULL, destsize);
599 ret = PyBytes_FromStringAndSize(NULL, destsize);
577 if (ret == NULL)
600 if (ret == NULL) {
578 return NULL;
601 return NULL;
602 }
579
603
580 dest = PyBytes_AS_STRING(ret);
604 dest = PyBytes_AS_STRING(ret);
581 memcopy(dest, &destlen, destsize, "dh/", 3);
605 memcopy(dest, &destlen, destsize, "dh/", 3);
@@ -587,30 +611,36 b' static PyObject *hashmangle(const char *'
587 char d = dest[destlen - 1];
611 char d = dest[destlen - 1];
588 /* After truncation, a directory name may end
612 /* After truncation, a directory name may end
589 in a space or dot, which are unportable. */
613 in a space or dot, which are unportable. */
590 if (d == '.' || d == ' ')
614 if (d == '.' || d == ' ') {
591 dest[destlen - 1] = '_';
615 dest[destlen - 1] = '_';
592 /* The + 3 is to account for "dh/" in the beginning */
616 /* The + 3 is to account for "dh/" in the
593 if (destlen > maxshortdirslen + 3)
617 * beginning */
618 }
619 if (destlen > maxshortdirslen + 3) {
594 break;
620 break;
621 }
595 charcopy(dest, &destlen, destsize, src[i]);
622 charcopy(dest, &destlen, destsize, src[i]);
596 p = -1;
623 p = -1;
597 } else if (p < dirprefixlen)
624 } else if (p < dirprefixlen) {
598 charcopy(dest, &destlen, destsize, src[i]);
625 charcopy(dest, &destlen, destsize, src[i]);
626 }
599 }
627 }
600
628
601 /* Rewind to just before the last slash copied. */
629 /* Rewind to just before the last slash copied. */
602 if (destlen > maxshortdirslen + 3)
630 if (destlen > maxshortdirslen + 3) {
603 do {
631 do {
604 destlen--;
632 destlen--;
605 } while (destlen > 0 && dest[destlen] != '/');
633 } while (destlen > 0 && dest[destlen] != '/');
634 }
606
635
607 if (destlen > 3) {
636 if (destlen > 3) {
608 if (lastslash > 0) {
637 if (lastslash > 0) {
609 char d = dest[destlen - 1];
638 char d = dest[destlen - 1];
610 /* The last directory component may be
639 /* The last directory component may be
611 truncated, so make it safe. */
640 truncated, so make it safe. */
612 if (d == '.' || d == ' ')
641 if (d == '.' || d == ' ') {
613 dest[destlen - 1] = '_';
642 dest[destlen - 1] = '_';
643 }
614 }
644 }
615
645
616 charcopy(dest, &destlen, destsize, '/');
646 charcopy(dest, &destlen, destsize, '/');
@@ -620,27 +650,32 b' static PyObject *hashmangle(const char *'
620 depends on the number of bytes left after accounting for
650 depends on the number of bytes left after accounting for
621 hash and suffix. */
651 hash and suffix. */
622 used = destlen + 40;
652 used = destlen + 40;
623 if (lastdot >= 0)
653 if (lastdot >= 0) {
624 used += len - lastdot - 1;
654 used += len - lastdot - 1;
655 }
625 slop = maxstorepathlen - used;
656 slop = maxstorepathlen - used;
626 if (slop > 0) {
657 if (slop > 0) {
627 Py_ssize_t basenamelen =
658 Py_ssize_t basenamelen =
628 lastslash >= 0 ? len - lastslash - 2 : len - 1;
659 lastslash >= 0 ? len - lastslash - 2 : len - 1;
629
660
630 if (basenamelen > slop)
661 if (basenamelen > slop) {
631 basenamelen = slop;
662 basenamelen = slop;
632 if (basenamelen > 0)
663 }
664 if (basenamelen > 0) {
633 memcopy(dest, &destlen, destsize, &src[lastslash + 1],
665 memcopy(dest, &destlen, destsize, &src[lastslash + 1],
634 basenamelen);
666 basenamelen);
667 }
635 }
668 }
636
669
637 /* Add hash and suffix. */
670 /* Add hash and suffix. */
638 for (i = 0; i < 20; i++)
671 for (i = 0; i < 20; i++) {
639 hexencode(dest, &destlen, destsize, sha[i]);
672 hexencode(dest, &destlen, destsize, sha[i]);
673 }
640
674
641 if (lastdot >= 0)
675 if (lastdot >= 0) {
642 memcopy(dest, &destlen, destsize, &src[lastdot],
676 memcopy(dest, &destlen, destsize, &src[lastdot],
643 len - lastdot - 1);
677 len - lastdot - 1);
678 }
644
679
645 assert(PyBytes_Check(ret));
680 assert(PyBytes_Check(ret));
646 Py_SIZE(ret) = destlen;
681 Py_SIZE(ret) = destlen;
@@ -677,13 +712,15 b' static int sha1hash(char hash[20], const'
677
712
678 shaobj = PyObject_CallFunction(shafunc, PY23("s#", "y#"), str, len);
713 shaobj = PyObject_CallFunction(shafunc, PY23("s#", "y#"), str, len);
679
714
680 if (shaobj == NULL)
715 if (shaobj == NULL) {
681 return -1;
716 return -1;
717 }
682
718
683 hashobj = PyObject_CallMethod(shaobj, "digest", "");
719 hashobj = PyObject_CallMethod(shaobj, "digest", "");
684 Py_DECREF(shaobj);
720 Py_DECREF(shaobj);
685 if (hashobj == NULL)
721 if (hashobj == NULL) {
686 return -1;
722 return -1;
723 }
687
724
688 if (!PyBytes_Check(hashobj) || PyBytes_GET_SIZE(hashobj) != 20) {
725 if (!PyBytes_Check(hashobj) || PyBytes_GET_SIZE(hashobj) != 20) {
689 PyErr_SetString(PyExc_TypeError,
726 PyErr_SetString(PyExc_TypeError,
@@ -714,8 +751,9 b' static PyObject *hashencode(const char *'
714 }
751 }
715
752
716 dirlen = _encodedir(dired, baselen, src, len);
753 dirlen = _encodedir(dired, baselen, src, len);
717 if (sha1hash(sha, dired, dirlen - 1) == -1)
754 if (sha1hash(sha, dired, dirlen - 1) == -1) {
718 return NULL;
755 return NULL;
756 }
719 lowerlen = _lowerencode(lowered, baselen, dired + 5, dirlen - 5);
757 lowerlen = _lowerencode(lowered, baselen, dired + 5, dirlen - 5);
720 auxlen = auxencode(auxed, baselen, lowered, lowerlen);
758 auxlen = auxencode(auxed, baselen, lowered, lowerlen);
721 return hashmangle(auxed, auxlen, sha);
759 return hashmangle(auxed, auxlen, sha);
@@ -727,18 +765,20 b' PyObject *pathencode(PyObject *self, PyO'
727 PyObject *pathobj, *newobj;
765 PyObject *pathobj, *newobj;
728 char *path;
766 char *path;
729
767
730 if (!PyArg_ParseTuple(args, "O:pathencode", &pathobj))
768 if (!PyArg_ParseTuple(args, "O:pathencode", &pathobj)) {
731 return NULL;
769 return NULL;
770 }
732
771
733 if (PyBytes_AsStringAndSize(pathobj, &path, &len) == -1) {
772 if (PyBytes_AsStringAndSize(pathobj, &path, &len) == -1) {
734 PyErr_SetString(PyExc_TypeError, "expected a string");
773 PyErr_SetString(PyExc_TypeError, "expected a string");
735 return NULL;
774 return NULL;
736 }
775 }
737
776
738 if (len > maxstorepathlen)
777 if (len > maxstorepathlen) {
739 newlen = maxstorepathlen + 2;
778 newlen = maxstorepathlen + 2;
740 else
779 } else {
741 newlen = len ? basicencode(NULL, 0, path, len + 1) : 1;
780 newlen = len ? basicencode(NULL, 0, path, len + 1) : 1;
781 }
742
782
743 if (newlen <= maxstorepathlen + 1) {
783 if (newlen <= maxstorepathlen + 1) {
744 if (newlen == len + 1) {
784 if (newlen == len + 1) {
@@ -754,8 +794,9 b' PyObject *pathencode(PyObject *self, PyO'
754 basicencode(PyBytes_AS_STRING(newobj), newlen, path,
794 basicencode(PyBytes_AS_STRING(newobj), newlen, path,
755 len + 1);
795 len + 1);
756 }
796 }
757 } else
797 } else {
758 newobj = hashencode(path, len + 1);
798 newobj = hashencode(path, len + 1);
799 }
759
800
760 return newobj;
801 return newobj;
761 }
802 }
@@ -41,8 +41,9 b' static struct mpatch_flist *lalloc(ssize'
41 {
41 {
42 struct mpatch_flist *a = NULL;
42 struct mpatch_flist *a = NULL;
43
43
44 if (size < 1)
44 if (size < 1) {
45 size = 1;
45 size = 1;
46 }
46
47
47 a = (struct mpatch_flist *)malloc(sizeof(struct mpatch_flist));
48 a = (struct mpatch_flist *)malloc(sizeof(struct mpatch_flist));
48 if (a) {
49 if (a) {
@@ -110,10 +111,12 b' static int gather(struct mpatch_flist *d'
110
111
111 while (s != src->tail) {
112 while (s != src->tail) {
112 int soffset = s->start;
113 int soffset = s->start;
113 if (!safeadd(offset, &soffset))
114 if (!safeadd(offset, &soffset)) {
114 break; /* add would overflow, oh well */
115 break; /* add would overflow, oh well */
115 if (soffset >= cut)
116 }
117 if (soffset >= cut) {
116 break; /* we've gone far enough */
118 break; /* we've gone far enough */
119 }
117
120
118 postend = offset;
121 postend = offset;
119 if (!safeadd(s->start, &postend) ||
122 if (!safeadd(s->start, &postend) ||
@@ -139,11 +142,13 b' static int gather(struct mpatch_flist *d'
139 if (!safesub(offset, &c)) {
142 if (!safesub(offset, &c)) {
140 break;
143 break;
141 }
144 }
142 if (s->end < c)
145 if (s->end < c) {
143 c = s->end;
146 c = s->end;
147 }
144 l = cut - offset - s->start;
148 l = cut - offset - s->start;
145 if (s->len < l)
149 if (s->len < l) {
146 l = s->len;
150 l = s->len;
151 }
147
152
148 offset += s->start + l - c;
153 offset += s->start + l - c;
149
154
@@ -176,8 +181,9 b' static int discard(struct mpatch_flist *'
176 if (!safeadd(offset, &cmpcut)) {
181 if (!safeadd(offset, &cmpcut)) {
177 break;
182 break;
178 }
183 }
179 if (cmpcut >= cut)
184 if (cmpcut >= cut) {
180 break;
185 break;
186 }
181
187
182 postend = offset;
188 postend = offset;
183 if (!safeadd(s->start, &postend)) {
189 if (!safeadd(s->start, &postend)) {
@@ -205,11 +211,13 b' static int discard(struct mpatch_flist *'
205 if (!safesub(offset, &c)) {
211 if (!safesub(offset, &c)) {
206 break;
212 break;
207 }
213 }
208 if (s->end < c)
214 if (s->end < c) {
209 c = s->end;
215 c = s->end;
216 }
210 l = cut - offset - s->start;
217 l = cut - offset - s->start;
211 if (s->len < l)
218 if (s->len < l) {
212 l = s->len;
219 l = s->len;
220 }
213
221
214 offset += s->start + l - c;
222 offset += s->start + l - c;
215 s->start = c;
223 s->start = c;
@@ -233,8 +241,9 b' static struct mpatch_flist *combine(stru'
233 struct mpatch_frag *bh, *ct;
241 struct mpatch_frag *bh, *ct;
234 int offset = 0, post;
242 int offset = 0, post;
235
243
236 if (a && b)
244 if (a && b) {
237 c = lalloc((lsize(a) + lsize(b)) * 2);
245 c = lalloc((lsize(a) + lsize(b)) * 2);
246 }
238
247
239 if (c) {
248 if (c) {
240
249
@@ -284,8 +293,9 b' int mpatch_decode(const char *bin, ssize'
284
293
285 /* assume worst case size, we won't have many of these lists */
294 /* assume worst case size, we won't have many of these lists */
286 l = lalloc(len / 12 + 1);
295 l = lalloc(len / 12 + 1);
287 if (!l)
296 if (!l) {
288 return MPATCH_ERR_NO_MEM;
297 return MPATCH_ERR_NO_MEM;
298 }
289
299
290 lt = l->tail;
300 lt = l->tail;
291
301
@@ -295,8 +305,9 b' int mpatch_decode(const char *bin, ssize'
295 lt->start = getbe32(bin + pos);
305 lt->start = getbe32(bin + pos);
296 lt->end = getbe32(bin + pos + 4);
306 lt->end = getbe32(bin + pos + 4);
297 lt->len = getbe32(bin + pos + 8);
307 lt->len = getbe32(bin + pos + 8);
298 if (lt->start < 0 || lt->start > lt->end || lt->len < 0)
308 if (lt->start < 0 || lt->start > lt->end || lt->len < 0) {
299 break; /* sanity check */
309 break; /* sanity check */
310 }
300 if (!safeadd(12, &pos)) {
311 if (!safeadd(12, &pos)) {
301 break;
312 break;
302 }
313 }
@@ -33,28 +33,36 b' static void handlestopsignal(int sig)'
33 {
33 {
34 sigset_t unblockset, oldset;
34 sigset_t unblockset, oldset;
35 struct sigaction sa, oldsa;
35 struct sigaction sa, oldsa;
36 if (sigemptyset(&unblockset) < 0)
36 if (sigemptyset(&unblockset) < 0) {
37 return;
37 return;
38 if (sigaddset(&unblockset, sig) < 0)
38 }
39 if (sigaddset(&unblockset, sig) < 0) {
39 return;
40 return;
41 }
40 memset(&sa, 0, sizeof(sa));
42 memset(&sa, 0, sizeof(sa));
41 sa.sa_handler = SIG_DFL;
43 sa.sa_handler = SIG_DFL;
42 sa.sa_flags = SA_RESTART;
44 sa.sa_flags = SA_RESTART;
43 if (sigemptyset(&sa.sa_mask) < 0)
45 if (sigemptyset(&sa.sa_mask) < 0) {
44 return;
46 return;
47 }
45
48
46 forwardsignal(sig);
49 forwardsignal(sig);
47 if (raise(sig) < 0) /* resend to self */
50 if (raise(sig) < 0) { /* resend to self */
48 return;
51 return;
49 if (sigaction(sig, &sa, &oldsa) < 0)
52 }
53 if (sigaction(sig, &sa, &oldsa) < 0) {
50 return;
54 return;
51 if (sigprocmask(SIG_UNBLOCK, &unblockset, &oldset) < 0)
55 }
56 if (sigprocmask(SIG_UNBLOCK, &unblockset, &oldset) < 0) {
52 return;
57 return;
58 }
53 /* resent signal will be handled before sigprocmask() returns */
59 /* resent signal will be handled before sigprocmask() returns */
54 if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0)
60 if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0) {
55 return;
61 return;
56 if (sigaction(sig, &oldsa, NULL) < 0)
62 }
63 if (sigaction(sig, &oldsa, NULL) < 0) {
57 return;
64 return;
65 }
58 }
66 }
59
67
60 /*
68 /*
@@ -81,37 +89,46 b' int setupsignalhandler(pid_t pid, pid_t '
81 * - SIGINT: usually generated by the terminal */
89 * - SIGINT: usually generated by the terminal */
82 sa.sa_handler = forwardsignaltogroup;
90 sa.sa_handler = forwardsignaltogroup;
83 sa.sa_flags = SA_RESTART;
91 sa.sa_flags = SA_RESTART;
84 if (sigemptyset(&sa.sa_mask) < 0)
92 if (sigemptyset(&sa.sa_mask) < 0) {
93 return -1;
94 }
95 if (sigaction(SIGHUP, &sa, NULL) < 0) {
85 return -1;
96 return -1;
86 if (sigaction(SIGHUP, &sa, NULL) < 0)
97 }
98 if (sigaction(SIGINT, &sa, NULL) < 0) {
87 return -1;
99 return -1;
88 if (sigaction(SIGINT, &sa, NULL) < 0)
100 }
89 return -1;
90
101
91 /* terminate frontend by double SIGTERM in case of server freeze */
102 /* terminate frontend by double SIGTERM in case of server freeze */
92 sa.sa_handler = forwardsignal;
103 sa.sa_handler = forwardsignal;
93 sa.sa_flags |= SA_RESETHAND;
104 sa.sa_flags |= SA_RESETHAND;
94 if (sigaction(SIGTERM, &sa, NULL) < 0)
105 if (sigaction(SIGTERM, &sa, NULL) < 0) {
95 return -1;
106 return -1;
107 }
96
108
97 /* notify the worker about window resize events */
109 /* notify the worker about window resize events */
98 sa.sa_flags = SA_RESTART;
110 sa.sa_flags = SA_RESTART;
99 if (sigaction(SIGWINCH, &sa, NULL) < 0)
111 if (sigaction(SIGWINCH, &sa, NULL) < 0) {
100 return -1;
112 return -1;
113 }
101 /* forward user-defined signals */
114 /* forward user-defined signals */
102 if (sigaction(SIGUSR1, &sa, NULL) < 0)
115 if (sigaction(SIGUSR1, &sa, NULL) < 0) {
103 return -1;
116 return -1;
104 if (sigaction(SIGUSR2, &sa, NULL) < 0)
117 }
118 if (sigaction(SIGUSR2, &sa, NULL) < 0) {
105 return -1;
119 return -1;
120 }
106 /* propagate job control requests to worker */
121 /* propagate job control requests to worker */
107 sa.sa_handler = forwardsignal;
122 sa.sa_handler = forwardsignal;
108 sa.sa_flags = SA_RESTART;
123 sa.sa_flags = SA_RESTART;
109 if (sigaction(SIGCONT, &sa, NULL) < 0)
124 if (sigaction(SIGCONT, &sa, NULL) < 0) {
110 return -1;
125 return -1;
126 }
111 sa.sa_handler = handlestopsignal;
127 sa.sa_handler = handlestopsignal;
112 sa.sa_flags = SA_RESTART;
128 sa.sa_flags = SA_RESTART;
113 if (sigaction(SIGTSTP, &sa, NULL) < 0)
129 if (sigaction(SIGTSTP, &sa, NULL) < 0) {
114 return -1;
130 return -1;
131 }
115
132
116 return 0;
133 return 0;
117 }
134 }
@@ -127,24 +144,31 b' int restoresignalhandler(void)'
127 memset(&sa, 0, sizeof(sa));
144 memset(&sa, 0, sizeof(sa));
128 sa.sa_handler = SIG_DFL;
145 sa.sa_handler = SIG_DFL;
129 sa.sa_flags = SA_RESTART;
146 sa.sa_flags = SA_RESTART;
130 if (sigemptyset(&sa.sa_mask) < 0)
147 if (sigemptyset(&sa.sa_mask) < 0) {
131 return -1;
148 return -1;
149 }
132
150
133 if (sigaction(SIGHUP, &sa, NULL) < 0)
151 if (sigaction(SIGHUP, &sa, NULL) < 0) {
134 return -1;
152 return -1;
135 if (sigaction(SIGTERM, &sa, NULL) < 0)
153 }
154 if (sigaction(SIGTERM, &sa, NULL) < 0) {
136 return -1;
155 return -1;
137 if (sigaction(SIGWINCH, &sa, NULL) < 0)
156 }
157 if (sigaction(SIGWINCH, &sa, NULL) < 0) {
138 return -1;
158 return -1;
139 if (sigaction(SIGCONT, &sa, NULL) < 0)
159 }
160 if (sigaction(SIGCONT, &sa, NULL) < 0) {
140 return -1;
161 return -1;
141 if (sigaction(SIGTSTP, &sa, NULL) < 0)
162 }
163 if (sigaction(SIGTSTP, &sa, NULL) < 0) {
142 return -1;
164 return -1;
165 }
143
166
144 /* ignore Ctrl+C while shutting down to make pager exits cleanly */
167 /* ignore Ctrl+C while shutting down to make pager exits cleanly */
145 sa.sa_handler = SIG_IGN;
168 sa.sa_handler = SIG_IGN;
146 if (sigaction(SIGINT, &sa, NULL) < 0)
169 if (sigaction(SIGINT, &sa, NULL) < 0) {
147 return -1;
170 return -1;
171 }
148
172
149 peerpid = 0;
173 peerpid = 0;
150 return 0;
174 return 0;
General Comments 0
You need to be logged in to leave comments. Login now