1 /* $OpenBSD: edit.c,v 1.19 2009/06/07 13:29:50 ray Exp $ */
4 * Written by Raymond Lai <ray@cyth.net>.
11 #include <sys/types.h>
27 int editit(const char *);
30 * Execute an editor on the specified pathname, which is interpreted
31 * from the shell. This means flags may be included.
33 * Returns -1 on error, or the exit value on success.
36 editit(const char *pathname)
38 sig_t sighup, sigint, sigquit, sigchld;
40 int saved_errno, st, ret = -1;
43 ed = getenv("VISUAL");
45 ed = getenv("EDITOR");
49 sighup = signal(SIGHUP, SIG_IGN);
50 sigint = signal(SIGINT, SIG_IGN);
51 sigquit = signal(SIGQUIT, SIG_IGN);
52 sigchld = signal(SIGCHLD, SIG_DFL);
53 if ((pid = fork()) == -1)
56 execlp(ed, ed, pathname, (char *)NULL);
59 while (waitpid(pid, &st, 0) == -1)
65 ret = WEXITSTATUS(st);
69 (void)signal(SIGHUP, sighup);
70 (void)signal(SIGINT, sigint);
71 (void)signal(SIGQUIT, sigquit);
72 (void)signal(SIGCHLD, sigchld);
78 * Parse edit command. Returns 0 on success, -1 on error.
81 eparse(const char *cmd, const char *left, const char *right)
87 char buf[BUFSIZ], *text;
89 /* Skip whitespace. */
96 /* Edit empty file. */
106 /* Neither column is blank, so print both. */
107 if (asprintf(&text, "%s\n%s\n", left, right) == -1)
108 err(2, "could not allocate memory");
113 /* Skip if there is no left column. */
117 if (asprintf(&text, "%s\n", left) == -1)
118 err(2, "could not allocate memory");
124 /* Skip if there is no right column. */
128 if (asprintf(&text, "%s\n", right) == -1)
129 err(2, "could not allocate memory");
137 /* Create temp file. */
138 if (asprintf(&filename, "%s/sdiff.XXXXXXXXXX", tmpdir) == -1)
140 if ((fd = mkstemp(filename)) == -1)
147 if ((nwritten = write(fd, text, len)) == -1 ||
148 (size_t)nwritten != len) {
149 warn("error writing to temp file");
155 /* text is no longer used. */
158 /* Edit temp file. */
159 if (editit(filename) == -1) {
160 warn("error editing %s", filename);
164 /* Open temporary file. */
165 if (!(file = fopen(filename, "r"))) {
166 warn("could not open edited file: %s", filename);
170 /* Copy temporary file contents to output file. */
171 for (nread = sizeof(buf); nread == sizeof(buf);) {
174 nread = fread(buf, sizeof(*buf), sizeof(buf), file);
175 /* Test for error or end of file. */
176 if (nread != sizeof(buf) &&
177 (ferror(file) || !feof(file))) {
178 warnx("error reading edited file: %s", filename);
183 * If we have nothing to read, break out of loop
184 * instead of writing nothing.
189 /* Write data we just read. */
190 nwritten = fwrite(buf, sizeof(*buf), nread, outfp);
191 if (nwritten != nread) {
192 warnx("error writing to output file");
197 /* We've reached the end of the temporary file, so remove it. */
198 if (unlink(filename))
199 warn("could not delete: %s", filename);