Skip to content

Commit

Permalink
Unlink the temp file sooner
Browse files Browse the repository at this point in the history
We only need the temp file to be present on the file system to run
xdg-mime on it. Once we have done that, we can unlink it and simply use
an fd to refer to it, seeking to the beginning each time.

This makes us more robust against wl-copy crashing (or getting killed),
in which case the file would be kept on the file system; this should no
longer be the case with this patch.

Related to #155
  • Loading branch information
bugaevc committed Mar 4, 2023
1 parent 065d6da commit dbaa684
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 23 deletions.
11 changes: 9 additions & 2 deletions src/types/copy-action.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static void do_send(struct source *source, const char *mime_type, int fd) {
/* Unset O_NONBLOCK */
fcntl(fd, F_SETFL, 0);

if (self->file_to_copy != NULL) {
if (self->fd_to_copy_from != -1) {
/* Copy the file to the given file descriptor
* by spawning an appropriate cat process.
*/
Expand All @@ -82,9 +82,11 @@ static void do_send(struct source *source, const char *mime_type, int fd) {
return;
}
if (pid == 0) {
dup2(self->fd_to_copy_from, STDIN_FILENO);
close(self->fd_to_copy_from);
dup2(fd, STDOUT_FILENO);
close(fd);
execlp("cat", "cat", self->file_to_copy, NULL);
execlp("cat", "cat", NULL);
perror("exec cat");
exit(1);
}
Expand All @@ -97,6 +99,11 @@ static void do_send(struct source *source, const char *mime_type, int fd) {
* instead.
*/
waitpid(pid, NULL, 0);
/* Seek back to the beginning of the file */
off_t rc = lseek(self->fd_to_copy_from, 0, SEEK_SET);
if (rc < 0) {
perror("lseek");
}
} else {
/* We'll perform the copy ourselves */
FILE *f = fdopen(fd, "w");
Expand Down
3 changes: 2 additions & 1 deletion src/types/copy-action.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ struct copy_action {

/* Exactly one of these fields must be non-null if the source
* is non-null, otherwise all these fields must be null.
* The null value for fd_to_copy_from is -1.
*/
const char *file_to_copy;
int fd_to_copy_from;
argv_t argv_to_copy;
struct {
const char *ptr;
Expand Down
45 changes: 25 additions & 20 deletions src/wl-copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,29 +81,13 @@ static void did_set_selection_callback(struct copy_action *copy_action) {
}
}

static void cleanup_and_exit(struct copy_action *copy_action, int code) {
/* We're done copying!
* All that's left to do now is to
* clean up after ourselves and exit.
*/
char *temp_file = (char *) copy_action->file_to_copy;
if (temp_file != NULL) {
/* Clean up our temporary file */
execlp("rm", "rm", "-r", dirname(temp_file), NULL);
perror("exec rm");
exit(1);
} else {
exit(code);
}
}

static void cancelled_callback(struct copy_action *copy_action) {
cleanup_and_exit(copy_action, 0);
exit(0);
}

static void pasted_callback(struct copy_action *copy_action) {
if (options.paste_once) {
cleanup_and_exit(copy_action, 0);
exit(0);
}
}

Expand Down Expand Up @@ -244,6 +228,7 @@ int main(int argc, argv_t argv) {

/* Create and initialize the copy action */
struct copy_action *copy_action = calloc(1, sizeof(struct copy_action));
copy_action->fd_to_copy_from = -1;
copy_action->device = device;
copy_action->primary = options.primary;

Expand All @@ -266,7 +251,28 @@ int main(int argc, argv_t argv) {
if (options.mime_type == NULL) {
options.mime_type = infer_mime_type_from_contents(temp_file);
}
copy_action->file_to_copy = temp_file;
copy_action->fd_to_copy_from = open(
temp_file,
O_RDONLY | O_CLOEXEC
);
if (copy_action->fd_to_copy_from < 0) {
perror("Failed to open temp file");
return 1;
}
/* Now, remove the temp file and its
* containing directory. We still keep
* access to the file through our open
* file descriptor.
*/
int rc = unlink(temp_file);
if (rc < 0) {
perror("Failed to unlink temp file");
}
rc = rmdir(dirname(temp_file));
if (rc < 0) {
perror("Failed to remove temp file directory");
}
free(temp_file);
}

/* Create the source */
Expand Down Expand Up @@ -300,6 +306,5 @@ int main(int argc, argv_t argv) {
while (wl_display_dispatch(wl_display) >= 0);

perror("wl_display_dispatch");
cleanup_and_exit(copy_action, 1);
return 1;
}

0 comments on commit dbaa684

Please sign in to comment.