annotate contrib/chg/util.c @ 35923:efbd04238029

cmdutil: convert _revertprefetch() to a generic stored file hook (API) This will be used by LFS to fetch required files in a group for multiple commands, prior to being accessed. That avoids the one-at-a-time fetch when the filelog wrapper goes to access it, and it is missing locally (which costs two round trips to the server.) The core command list that needs this is probably at least: - annotate - archive (which is also used by extdiff) - cat - diff - export - grep - verify (sadly) - anything that has the '{data}' template There are no core users of the revert prefetch hook, and never have been since it was introduced in 45e02cfad4bd for remotefilelog. Thanks to Yuya for figuring out a way to reliably trigger the deprecated warning. Unfortunately, it wanted to blame the caller of revert. Passing along an adjusted stack level seemed the least bad choice (although it still blames a core function). One thing to note is that the store lock isn't being held when this is called. I'm not at all familiar with remotefilelog or its locking requirements, so this may not be a big deal. Currently, LFS doesn't hold a lock when downloading files. Even though largefiles doesn't either, I'm starting to think it should, and maybe the .hg/store/lock isn't good enough to cover the globally shared cache. .. api:: The cmdutil._revertprefetch() hook point for prefetching stored files has been replaced by the command agnostic cmdutil._prefetchfiles(). The new function takes a list of files, instead of a list of lists of files.
author Matt Harbison <matt_harbison@yahoo.com>
date Sun, 04 Feb 2018 14:14:28 -0500
parents b94db1780365
children 9724f54923ec
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
1 /*
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
2 * Utility functions
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
3 *
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
4 * Copyright (c) 2011 Yuya Nishihara <yuya@tcha.org>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
5 *
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
6 * This software may be used and distributed according to the terms of the
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
7 * GNU General Public License version 2 or any later version.
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
8 */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
9
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
10 #include <errno.h>
28855
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
11 #include <fcntl.h>
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
12 #include <signal.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
13 #include <stdarg.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
14 #include <stdio.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
15 #include <stdlib.h>
28084
3fc45956c978 chg: initialize sigaction fields more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 28060
diff changeset
16 #include <string.h>
34309
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
17 #include <sys/time.h>
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
18 #include <sys/types.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
19 #include <sys/wait.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
20 #include <unistd.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
21
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
22 #include "util.h"
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
23
28787
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
24 static int colorenabled = 0;
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
25
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
26 static inline void fsetcolor(FILE *fp, const char *code)
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
27 {
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
28 if (!colorenabled)
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
29 return;
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
30 fprintf(fp, "\033[%sm", code);
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
31 }
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
32
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
33 static void vabortmsgerrno(int no, const char *fmt, va_list args)
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
34 {
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
35 fsetcolor(stderr, "1;31");
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
36 fputs("chg: abort: ", stderr);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
37 vfprintf(stderr, fmt, args);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
38 if (no != 0)
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
39 fprintf(stderr, " (errno = %d, %s)", no, strerror(no));
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
40 fsetcolor(stderr, "");
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
41 fputc('\n', stderr);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
42 exit(255);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
43 }
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
44
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
45 void abortmsg(const char *fmt, ...)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
46 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
47 va_list args;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
48 va_start(args, fmt);
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
49 vabortmsgerrno(0, fmt, args);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
50 va_end(args);
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
51 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
52
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
53 void abortmsgerrno(const char *fmt, ...)
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
54 {
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
55 int no = errno;
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
56 va_list args;
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
57 va_start(args, fmt);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
58 vabortmsgerrno(no, fmt, args);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
59 va_end(args);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
60 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
61
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
62 static int debugmsgenabled = 0;
34309
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
63 static double debugstart = 0;
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
64
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
65 static double now() {
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
66 struct timeval t;
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
67 gettimeofday(&t, NULL);
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
68 return t.tv_usec / 1e6 + t.tv_sec;
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
69 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
70
28787
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
71 void enablecolor(void)
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
72 {
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
73 colorenabled = 1;
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
74 }
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
75
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
76 void enabledebugmsg(void)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
77 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
78 debugmsgenabled = 1;
34309
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
79 debugstart = now();
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
80 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
81
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
82 void debugmsg(const char *fmt, ...)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
83 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
84 if (!debugmsgenabled)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
85 return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
86
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
87 va_list args;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
88 va_start(args, fmt);
28787
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
89 fsetcolor(stderr, "1;30");
34309
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
90 fprintf(stderr, "chg: debug: %4.6f ", now() - debugstart);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
91 vfprintf(stderr, fmt, args);
28787
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
92 fsetcolor(stderr, "");
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
93 fputc('\n', stderr);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
94 va_end(args);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
95 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
96
28854
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
97 void fchdirx(int dirfd)
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
98 {
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
99 int r = fchdir(dirfd);
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
100 if (r == -1)
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
101 abortmsgerrno("failed to fchdir");
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
102 }
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
103
28855
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
104 void fsetcloexec(int fd)
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
105 {
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
106 int flags = fcntl(fd, F_GETFD);
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
107 if (flags < 0)
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
108 abortmsgerrno("cannot get flags of fd %d", fd);
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
109 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
110 abortmsgerrno("cannot set flags of fd %d", fd);
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
111 }
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
112
28165
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
113 void *mallocx(size_t size)
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
114 {
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
115 void *result = malloc(size);
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
116 if (!result)
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
117 abortmsg("failed to malloc");
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
118 return result;
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
119 }
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
120
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
121 void *reallocx(void *ptr, size_t size)
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
122 {
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
123 void *result = realloc(ptr, size);
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
124 if (!result)
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
125 abortmsg("failed to realloc");
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
126 return result;
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
127 }
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
128
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
129 /*
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
130 * Execute a shell command in mostly the same manner as system(), with the
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
131 * give environment variables, after chdir to the given cwd. Returns a status
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
132 * code compatible with the Python subprocess module.
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
133 */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
134 int runshellcmd(const char *cmd, const char *envp[], const char *cwd)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
135 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
136 enum { F_SIGINT = 1, F_SIGQUIT = 2, F_SIGMASK = 4, F_WAITPID = 8 };
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
137 unsigned int doneflags = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
138 int status = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
139 struct sigaction newsa, oldsaint, oldsaquit;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
140 sigset_t oldmask;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
141
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
142 /* block or mask signals just as system() does */
28084
3fc45956c978 chg: initialize sigaction fields more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 28060
diff changeset
143 memset(&newsa, 0, sizeof(newsa));
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
144 newsa.sa_handler = SIG_IGN;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
145 newsa.sa_flags = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
146 if (sigemptyset(&newsa.sa_mask) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
147 goto done;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
148 if (sigaction(SIGINT, &newsa, &oldsaint) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
149 goto done;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
150 doneflags |= F_SIGINT;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
151 if (sigaction(SIGQUIT, &newsa, &oldsaquit) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
152 goto done;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
153 doneflags |= F_SIGQUIT;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
154
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
155 if (sigaddset(&newsa.sa_mask, SIGCHLD) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
156 goto done;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
157 if (sigprocmask(SIG_BLOCK, &newsa.sa_mask, &oldmask) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
158 goto done;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
159 doneflags |= F_SIGMASK;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
160
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
161 pid_t pid = fork();
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
162 if (pid < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
163 goto done;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
164 if (pid == 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
165 sigaction(SIGINT, &oldsaint, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
166 sigaction(SIGQUIT, &oldsaquit, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
167 sigprocmask(SIG_SETMASK, &oldmask, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
168 if (cwd && chdir(cwd) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
169 _exit(127);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
170 const char *argv[] = {"sh", "-c", cmd, NULL};
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
171 if (envp) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
172 execve("/bin/sh", (char **)argv, (char **)envp);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
173 } else {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
174 execv("/bin/sh", (char **)argv);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
175 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
176 _exit(127);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
177 } else {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
178 if (waitpid(pid, &status, 0) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
179 goto done;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
180 doneflags |= F_WAITPID;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
181 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
182
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
183 done:
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
184 if (doneflags & F_SIGINT)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
185 sigaction(SIGINT, &oldsaint, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
186 if (doneflags & F_SIGQUIT)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
187 sigaction(SIGQUIT, &oldsaquit, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
188 if (doneflags & F_SIGMASK)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
189 sigprocmask(SIG_SETMASK, &oldmask, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
190
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
191 /* no way to report other errors, use 127 (= shell termination) */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
192 if (!(doneflags & F_WAITPID))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
193 return 127;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
194 if (WIFEXITED(status))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
195 return WEXITSTATUS(status);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
196 if (WIFSIGNALED(status))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
197 return -WTERMSIG(status);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
198 return 127;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
199 }