Blame


1 0548291a 2024-06-25 op /*
2 0548291a 2024-06-25 op * Copyright (c) 2024 Omar Polo <op@omarpolo.com>
3 0548291a 2024-06-25 op *
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.
7 0548291a 2024-06-25 op *
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.
15 0548291a 2024-06-25 op */
16 0548291a 2024-06-25 op
17 0548291a 2024-06-25 op #include "compat.h"
18 0548291a 2024-06-25 op
19 0548291a 2024-06-25 op #include <sys/wait.h>
20 0548291a 2024-06-25 op
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>
28 0548291a 2024-06-25 op
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"
32 0548291a 2024-06-25 op
33 0548291a 2024-06-25 op #define TMPFILE "/tmp/telescope.XXXXXXXXXX"
34 0548291a 2024-06-25 op
35 0548291a 2024-06-25 op int
36 0548291a 2024-06-25 op exec_cmd(char **argv, enum exec_mode mode)
37 0548291a 2024-06-25 op {
38 0548291a 2024-06-25 op char **t;
39 0548291a 2024-06-25 op int s, fd, ret;
40 0548291a 2024-06-25 op pid_t pid;
41 0548291a 2024-06-25 op
42 0548291a 2024-06-25 op if (argv == NULL)
43 0548291a 2024-06-25 op return (-1);
44 0548291a 2024-06-25 op
45 0548291a 2024-06-25 op if (mode == EXEC_FOREGROUND) {
46 0548291a 2024-06-25 op ui_suspend();
47 0548291a 2024-06-25 op
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");
52 0548291a 2024-06-25 op fflush(NULL);
53 0548291a 2024-06-25 op }
54 0548291a 2024-06-25 op
55 0548291a 2024-06-25 op switch (pid = fork()) {
56 0548291a 2024-06-25 op case -1:
57 0548291a 2024-06-25 op message("failed to fork: %s", strerror(errno));
58 0548291a 2024-06-25 op return (-1);
59 0548291a 2024-06-25 op case 0:
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");
63 0548291a 2024-06-25 op _exit(1);
64 0548291a 2024-06-25 op }
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);
68 0548291a 2024-06-25 op if (fd > 2)
69 0548291a 2024-06-25 op close(fd);
70 0548291a 2024-06-25 op }
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);
77 0548291a 2024-06-25 op }
78 0548291a 2024-06-25 op _exit(1);
79 0548291a 2024-06-25 op }
80 0548291a 2024-06-25 op
81 0548291a 2024-06-25 op if (mode == EXEC_BACKGROUND)
82 0548291a 2024-06-25 op return (0);
83 0548291a 2024-06-25 op
84 0548291a 2024-06-25 op do {
85 0548291a 2024-06-25 op ret = waitpid(pid, &s, 0);
86 0548291a 2024-06-25 op } while (ret == -1 && errno == EINTR);
87 0548291a 2024-06-25 op
88 0548291a 2024-06-25 op ui_resume();
89 0548291a 2024-06-25 op
90 0548291a 2024-06-25 op if (WIFSIGNALED(s) || WEXITSTATUS(s) != 0) {
91 0548291a 2024-06-25 op message("%s failed", *argv);
92 0548291a 2024-06-25 op return (-1);
93 0548291a 2024-06-25 op }
94 0548291a 2024-06-25 op
95 0548291a 2024-06-25 op return (0);
96 0548291a 2024-06-25 op }
97 0548291a 2024-06-25 op
98 0548291a 2024-06-25 op FILE *
99 0548291a 2024-06-25 op exec_editor(void *data, size_t len)
100 0548291a 2024-06-25 op {
101 0548291a 2024-06-25 op FILE *fp;
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];
105 0548291a 2024-06-25 op int fd;
106 0548291a 2024-06-25 op
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);
111 0548291a 2024-06-25 op }
112 0548291a 2024-06-25 op (void) write(fd, data, len);
113 0548291a 2024-06-25 op close(fd);
114 0548291a 2024-06-25 op
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;
118 0548291a 2024-06-25 op
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;
122 0548291a 2024-06-25 op
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);
126 0548291a 2024-06-25 op }
127 0548291a 2024-06-25 op
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);
132 0548291a 2024-06-25 op }
133 0548291a 2024-06-25 op (void) unlink(sfn);
134 0548291a 2024-06-25 op
135 0548291a 2024-06-25 op return (fp);
136 0548291a 2024-06-25 op }