By the way, a largely unrelated thought: rather than writing the `.nnncp` file to home directory (some of us consider dotfiles a pollution) or $TMPDIR (wholly insecure), have you considered writing to something like `XDG_RUNTIME_DIR` [1], e.g., under `/var/run`?
[1] https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
No. A couple of problems:
1. `rm -Ir`: you're explicitly asking for interactive confirmation when running rm from xargs, where stdin is consumed, so that shouldn't work anywhere, not just on macOS.
Same goes for confirmations in cp and mv.
2. `cp --preserve=all`: that's coreutils only.
3. `mv -t`: that's coreutils only.
Please check FreeBSD man pages, e.g. https://www.freebsd.org/cgi/man.cgi?query=mv.
Oh, you're talking about copying to clipboard. That can be fuzzy, being LF-delimited is totally fine there. But input into xargs cannot, it must be 0-delimited.
I don't think you can mimic true copy to clipboard in a proper GUI application. On macOS for instance, you need AppKit for that, not something you can do from C.[1] Outside macOS, X clipboard definitely can be manipulated from C, but X is not the only window system.
[1] https://developer.apple.com/documentation/appkit/nspasteboard
- `touch foo bar $'foo\nbar'`.
- Copy the three files from Finder.
- Paste into TextEdit:
```
bar
foo
foo?bar
```
- Paste into terminal:
```
/private/tmp/test/bar /private/tmp/test/foo /private/tmp/test/foo\
bar
```
Okay I'm not sure why a GUI file manager is involved, I only read a bit of the code around select keywords. You obviously know the code and I don't, so I'll restrict my comments to a very specific concern: if you want to use xargs robustly, you have to 0-delimit paths.
I don't know X clipboard at all, but my macOS clipboard can hold multiple objects — plain text, rich text, file path, image, etc. (sort of like multipart); an xargs-compatible text buffer / plain text file clearly isn't as powerful. The best it can do is to 0-delimit. Of course, you can go into fancy serialization territory too, but that's probably unnecessary.
Rewrite URL copying with screen buffer
======================================
I was reminded tonight, by chance, of this feature, which I intended to rewrite when I first saw it, but then forgot.
---
A couple of issues:
- Avoid race condition with a proper mkstemp'ed file. The primary purpose of
this commit.
- The copier mode shouldn't be called `ext_file` because it sounds like a
generic writing to then reading from an external file (btw, what's an
internal file?), when it's really just GNU Screen-specific. So call it what
it is.
- Enumerate all possible values of copier_mode, then leave one final
theoretically unreachable else clause. Makes the final case easier to
understand without reading a lot of prior code. Like switch/case/default. (I
actually would like a switch in Python, but PEP 3103 was rejected due to "A
quick poll during my keynote presentation at PyCon 2007 shows this proposal
has no popular support. I therefore reject it." I digress.)
I grokked the code a bit, and now I see what you're doing, and I sort of see what your dilemma is. Are you worried about having NUL's in the middle of your buffer? Those makes your buffer invalid as C-strings, sure, but they don't really affect your fwrite, so I don't see the problem of replacing LF with NUL. I mean, this is totally fine:
```c
#include <stdio.h>
int main(int argc, char **argv) {
char buf[] = "abc\0def";
FILE *fp = fopen("tmp.txt", "w");
fwrite(buf, 1, sizeof(buf), fp);
return 0;
}
```
> filenames are separated by newlines.
Okay, yeah, that's an antipattern because paths could contain newlines. Should be NUL-delimited.
Consider three files, `foo`, `bar`, and `$'foo\nbar'`. Write `$'foo\nbar'`, use LF as delimiter, remove — bam, `foo` and `bar` are gone.
> The file is delimited by EOF
Not sure what you mean by that, EOF is not a character...
> The file is not written to every time a selection is made. The data is stored in an internal buffer and the final output is written to the file. This was done to reduce fs IOs.
That doesn't sound incompatible with NUL-delimitation?
> I don't have an extra minute to spare
No problem, fixing bugs on an open source project is not your job...
> My problem is I don't own a Mac to test the patch. Anyway, I will have to wait till someone can send in a tested one.
Have you considered running FreeBSD in a VM with say Vagrant? macOS is pretty close to FreeBSD in terms of linage, so most BSD-foundational compat issues manifest on FreeBSD too.
> g_cppath: path to the file which has the list of (absolute paths of) selected files. The file paths are separated by newlines.
I'm confused. Is this a file written by the program? If so, why not write it as NUL-delimited? Isn't `xargs -0` specifically designed for this, because you simply can't safely write a list of files with newline as delimiter (because file paths may contain newlines)?
I'm afraid looking at immediate surrounding code doesn't give me an idea of what the code is doing (e.g., I'm not sure what this `g_cppath` is, and why both `-0` and `-d '\n'` are used, which are ostensibly conflicting), so it's hard for me to cook up a patch quickly.
In general, using coreutils or other GNU utilities as basis for cross-platform code is a very bad idea because they have a lot more options (I love coreutils, but still). Better look at FreeBSD/OpenBSD too, or even stick to POSIX. Here are my scripts for opening FreeBSD/OpenBSD/POSIX man pages:
`freebsdman`:
```sh
#!/usr/bin/env bash
if [[ "$1" == [12345678] ]]; then
section=$1
shift
fi
for topic; do
open "https://www.freebsd.org/cgi/man.cgi?query=$topic${section:+&sektion=$section}"
done
```
https://www.freebsd.org/cgi/man.cgi?query=xargs
`openbsdman`:
```sh
#!/usr/bin/env bash
if [[ "$1" == [12345678] ]]; then
section=$1
shift
fi
for topic; do
if [[ -n $section ]]; then
open "http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man$section/$topic.$section"
else
open "http://www.openbsd.org/cgi-bin/man.cgi?query=$topic"
fi
done
```
https://man.openbsd.org/xargs
`posixman`:
```sh
#!/usr/bin/env bash
for utility; do
open "http://pubs.opengroup.org/onlinepubs/9699919799/utilities/$utility.html"
done
```
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/xargs.html