2 0548291a 2024-06-25 op * Copyright (c) 2024 Omar Polo <op@omarpolo.com>
4 0548291a 2024-06-25 op * Permission to use, copy, modify, and distribute this software for any
5 0548291a 2024-06-25 op * purpose with or without fee is hereby granted, provided that the above
6 0548291a 2024-06-25 op * copyright notice and this permission notice appear in all copies.
8 0548291a 2024-06-25 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 0548291a 2024-06-25 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 0548291a 2024-06-25 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 0548291a 2024-06-25 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 0548291a 2024-06-25 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 0548291a 2024-06-25 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 0548291a 2024-06-25 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 0548291a 2024-06-25 op #include "compat.h"
19 0548291a 2024-06-25 op #include <sys/wait.h>
21 0548291a 2024-06-25 op #include <errno.h>
22 0548291a 2024-06-25 op #include <fcntl.h>
23 0548291a 2024-06-25 op #include <stdio.h>
24 0548291a 2024-06-25 op #include <stdlib.h>
25 0548291a 2024-06-25 op #include <stdint.h>
26 0548291a 2024-06-25 op #include <string.h>
27 0548291a 2024-06-25 op #include <unistd.h>
29 0548291a 2024-06-25 op #include "exec.h"
30 0548291a 2024-06-25 op #include "minibuffer.h"
31 0548291a 2024-06-25 op #include "ui.h"
33 0548291a 2024-06-25 op #define TMPFILE "/tmp/telescope.XXXXXXXXXX"
36 0548291a 2024-06-25 op exec_cmd(char **argv, enum exec_mode mode)
39 0548291a 2024-06-25 op int s, fd, ret;
42 0548291a 2024-06-25 op if (argv == NULL)
45 0548291a 2024-06-25 op if (mode == EXEC_FOREGROUND) {
48 0548291a 2024-06-25 op fprintf(stderr, "%s: running", getprogname());
49 0548291a 2024-06-25 op for (t = argv; *t; ++t)
50 0548291a 2024-06-25 op fprintf(stderr, " %s", *t);
51 0548291a 2024-06-25 op fprintf(stderr, "\n");
55 0548291a 2024-06-25 op switch (pid = fork()) {
57 0548291a 2024-06-25 op message("failed to fork: %s", strerror(errno));
60 0548291a 2024-06-25 op if (mode == EXEC_BACKGROUND) {
61 0548291a 2024-06-25 op if ((fd = open("/dev/null", O_RDWR)) == -1) {
62 0548291a 2024-06-25 op warn("can't open /dev/null");
65 0548291a 2024-06-25 op (void)dup2(fd, 0);
66 0548291a 2024-06-25 op (void)dup2(fd, 1);
67 0548291a 2024-06-25 op (void)dup2(fd, 2);
71 0548291a 2024-06-25 op execvp(argv[0], argv);
72 0548291a 2024-06-25 op if (mode == EXEC_FOREGROUND) {
73 0548291a 2024-06-25 op warn("can't exec \"%s\"", argv[0]);
74 0548291a 2024-06-25 op fprintf(stderr, "Press enter to continue");
75 0548291a 2024-06-25 op fflush(stderr);
76 0548291a 2024-06-25 op read(0, &s, 1);
81 0548291a 2024-06-25 op if (mode == EXEC_BACKGROUND)
85 0548291a 2024-06-25 op ret = waitpid(pid, &s, 0);
86 0548291a 2024-06-25 op } while (ret == -1 && errno == EINTR);
90 0548291a 2024-06-25 op if (WIFSIGNALED(s) || WEXITSTATUS(s) != 0) {
91 0548291a 2024-06-25 op message("%s failed", *argv);
99 0548291a 2024-06-25 op exec_editor(void *data, size_t len)
102 0548291a 2024-06-25 op char *editor;
103 0548291a 2024-06-25 op char sfn[sizeof(TMPFILE)];
104 0548291a 2024-06-25 op char *argv[3];
107 0548291a 2024-06-25 op strlcpy(sfn, TMPFILE, sizeof(sfn));
108 0548291a 2024-06-25 op if ((fd = mkstemp(sfn)) == -1) {
109 0548291a 2024-06-25 op message("failed to create a temp file: %s", strerror(errno));
110 0548291a 2024-06-25 op return (NULL);
112 0548291a 2024-06-25 op (void) write(fd, data, len);
115 0548291a 2024-06-25 op if ((editor = getenv("VISUAL")) == NULL &&
116 0548291a 2024-06-25 op (editor = getenv("EDITOR")) == NULL)
117 0548291a 2024-06-25 op editor = (char *)DEFAULT_EDITOR;
119 0548291a 2024-06-25 op argv[0] = editor;
120 0548291a 2024-06-25 op argv[1] = sfn;
121 0548291a 2024-06-25 op argv[2] = NULL;
123 0548291a 2024-06-25 op if (exec_cmd(argv, EXEC_FOREGROUND) == -1) {
124 0548291a 2024-06-25 op (void) unlink(sfn);
125 0548291a 2024-06-25 op return (NULL);
128 0548291a 2024-06-25 op if ((fp = fopen(sfn, "r")) == NULL) {
129 0548291a 2024-06-25 op message("can't open temp file!");
130 0548291a 2024-06-25 op (void) unlink(sfn);
131 0548291a 2024-06-25 op return (NULL);
133 0548291a 2024-06-25 op (void) unlink(sfn);