1 /* $OpenBSD: edit.c,v 1.19 2009/06/07 13:29:50 ray Exp $ */
4 * Written by Raymond Lai <ray@cyth.net>.
24 cleanup(const char *filename)
28 err(2, "could not delete: %s", filename);
33 * Execute an editor on the specified pathname, which is interpreted
34 * from the shell. This means flags may be included.
36 * Returns -1 on error, or the exit value on success.
39 editit(const char *pathname)
41 sig_t sighup, sigint, sigquit, sigchld;
43 int saved_errno, st, ret = -1;
46 ed = getenv("VISUAL");
48 ed = getenv("EDITOR");
52 sighup = signal(SIGHUP, SIG_IGN);
53 sigint = signal(SIGINT, SIG_IGN);
54 sigquit = signal(SIGQUIT, SIG_IGN);
55 sigchld = signal(SIGCHLD, SIG_DFL);
56 if ((pid = fork()) == -1)
59 execlp(ed, ed, pathname, (char *)NULL);
62 while (waitpid(pid, &st, 0) == -1)
68 ret = WEXITSTATUS(st);
72 (void)signal(SIGHUP, sighup);
73 (void)signal(SIGINT, sigint);
74 (void)signal(SIGQUIT, sigquit);
75 (void)signal(SIGCHLD, sigchld);
81 * Parse edit command. Returns 0 on success, -1 on error.
84 eparse(const char *cmd, const char *left, const char *right)
90 char buf[BUFSIZ], *text;
92 /* Skip whitespace. */
99 /* Edit empty file. */
109 /* Neither column is blank, so print both. */
110 if (asprintf(&text, "%s\n%s\n", left, right) == -1)
111 err(2, "could not allocate memory");
116 /* Skip if there is no left column. */
120 if (asprintf(&text, "%s\n", left) == -1)
121 err(2, "could not allocate memory");
127 /* Skip if there is no right column. */
131 if (asprintf(&text, "%s\n", right) == -1)
132 err(2, "could not allocate memory");
140 /* Create temp file. */
141 if (asprintf(&filename, "%s/sdiff.XXXXXXXXXX", tmpdir) == -1)
143 if ((fd = mkstemp(filename)) == -1)
150 if ((nwritten = write(fd, text, len)) == -1 ||
151 (size_t)nwritten != len) {
152 warn("error writing to temp file");
158 /* text is no longer used. */
161 /* Edit temp file. */
162 if (editit(filename) == -1) {
163 warn("error editing %s", filename);
167 /* Open temporary file. */
168 if (!(file = fopen(filename, "r"))) {
169 warn("could not open edited file: %s", filename);
173 /* Copy temporary file contents to output file. */
174 for (nread = sizeof(buf); nread == sizeof(buf);) {
177 nread = fread(buf, sizeof(*buf), sizeof(buf), file);
178 /* Test for error or end of file. */
179 if (nread != sizeof(buf) &&
180 (ferror(file) || !feof(file))) {
181 warnx("error reading edited file: %s", filename);
186 * If we have nothing to read, break out of loop
187 * instead of writing nothing.
192 /* Write data we just read. */
193 nwritten = fwrite(buf, sizeof(*buf), nread, outfp);
194 if (nwritten != nread) {
195 warnx("error writing to output file");
200 /* We've reached the end of the temporary file, so remove it. */
201 if (unlink(filename))
202 warn("could not delete: %s", filename);