Re: [hackers] [PATCH][sbase] paste: Allow null delim
> This has nothing to do with getopt(). This is about how the shell parses > and splits words into arguments. -d"" Erf of course, put that on the fever. ^^
Re: [hackers] [PATCH][sbase] paste: Allow null delim
On Thu, Mar 5, 2020, 02:16 Quentin Rameau wrote: > > On Thu, 5 Mar 2020 01:42:37 -0800 > Michael Forney wrote: > > > >> and `-d""` is invalid, since paste(1) must follow the > > >> utility syntax guidelines (guideline 7). > > > > > > Not sure what you mean there, -d"" is the concatenation of -d and > > > '', which is standard. > > > Did you quote the correct guideline? “Guideline 7: Option-arguments > > > should not be optional.” here there's an option-argument, that's an > > > empty string. > > > > I guess it's a combination of 6 and 7. Option arguments must be > > separate parameters and non-optional (unless specified otherwise). > > There is an exception made that allows conforming implementations to > > accept an option adjacent with its option argument in the same > > argument, but I think this only makes sense if the option-argument is > > non-empty. > > > > POSIX says > > > > The construct '\0' is used to mean "no separator" because historical > > versions of paste did not follow the syntax guidelines, and the > > command: > > > > paste -d"" ... > > > > could not be handled properly by getopt(). > > > > I think this implies that `paste -d""` is no longer valid, due to the > > requirements of the syntax guidelines. > > Rather it's due to a getopt() limitation with the (not so) special case > of an empty string option-argument, but I'm not sure why. This has nothing to do with getopt(). This is about how the shell parses and splits words into arguments. -d"" is exactly the same as -d. It is the same word, adding an empty string to the end of a string does not change that original string. There is no argument to -d there. If you wanted to -d"" to pass two arguments "-d" and "" then you'd have to write a new shell to do that. As it stands shells pass on "-d" in argv when they come across -d"".
Re: [hackers] [PATCH][sbase] paste: Allow null delim
On Thu, 5 Mar 2020 01:42:37 -0800 Michael Forney wrote: > On 2020-03-05, Quentin Rameau wrote: > >> Looking at POSIX, I see that `-d '\0'` must be supported, `-d ""` > >> is unspecified > > > > I don't think so, -d "" is just a list with an empty string. > > So -d '\0' is equivalent to -d '', '\0' is here to let the user > > express an empty string in a list, which wouldn't be possible > > otherwise (like how would one specify empty string in a list like > > 'abcd'). > > Here is a direct quote from POSIX: > > The commands: > > paste -d "\0" ... > paste -d "" ... > > are not necessarily equivalent; the latter is not specified by > this volume of POSIX.1-2017 and may result in an error. My bad, I didn't read that far. But, > >> and `-d""` is invalid, since paste(1) must follow the > >> utility syntax guidelines (guideline 7). > > > > Not sure what you mean there, -d"" is the concatenation of -d and > > '', which is standard. > > Did you quote the correct guideline? “Guideline 7: Option-arguments > > should not be optional.” here there's an option-argument, that's an > > empty string. > > I guess it's a combination of 6 and 7. Option arguments must be > separate parameters and non-optional (unless specified otherwise). > There is an exception made that allows conforming implementations to > accept an option adjacent with its option argument in the same > argument, but I think this only makes sense if the option-argument is > non-empty. > > POSIX says > > The construct '\0' is used to mean "no separator" because historical > versions of paste did not follow the syntax guidelines, and the > command: > > paste -d"" ... > > could not be handled properly by getopt(). > > I think this implies that `paste -d""` is no longer valid, due to the > requirements of the syntax guidelines. Rather it's due to a getopt() limitation with the (not so) special case of an empty string option-argument, but I'm not sure why. The utility guidelines permits concatenating options and option-arguments, while it's true that the prefered syntax is to separate them. 12.1, 2.a: “If the SYNOPSIS of a standard utility shows an option with a mandatory option-argument (as with [ -c option_argument] in the example), a conforming application shall use separate arguments for that option and its option-argument. However, a conforming implementation shall also permit applications to specify the option and option-argument in the same argument string without intervening characters.” Without commenting on the patch itself, I think it's fine to allow '\0' and '', especially as we don't use getopt(), partly due to it being broken in most implementations (and having such limitations?), and the standards says it's unspecified, not undefinied.
Re: [hackers] [PATCH][sbase] paste: Allow null delim
On 2020-03-05, Quentin Rameau wrote: >> Looking at POSIX, I see that `-d '\0'` must be supported, `-d ""` is >> unspecified > > I don't think so, -d "" is just a list with an empty string. > So -d '\0' is equivalent to -d '', '\0' is here to let the user express > an empty string in a list, which wouldn't be possible otherwise (like > how would one specify empty string in a list like 'abcd'). Here is a direct quote from POSIX: The commands: paste -d "\0" ... paste -d "" ... are not necessarily equivalent; the latter is not specified by this volume of POSIX.1-2017 and may result in an error. >> and `-d""` is invalid, since paste(1) must follow the >> utility syntax guidelines (guideline 7). > > Not sure what you mean there, -d"" is the concatenation of -d and '', > which is standard. > Did you quote the correct guideline? “Guideline 7: Option-arguments > should not be optional.” here there's an option-argument, that's an > empty string. I guess it's a combination of 6 and 7. Option arguments must be separate parameters and non-optional (unless specified otherwise). There is an exception made that allows conforming implementations to accept an option adjacent with its option argument in the same argument, but I think this only makes sense if the option-argument is non-empty. POSIX says The construct '\0' is used to mean "no separator" because historical versions of paste did not follow the syntax guidelines, and the command: paste -d"" ... could not be handled properly by getopt(). I think this implies that `paste -d""` is no longer valid, due to the requirements of the syntax guidelines.
[hackers] [sbase] chmod: Remove -HLP flags, and ignore symlinks during traversal || Michael Forney
commit 3e160b616a183798e3dba34b93651a27851b1886 Author: Michael Forney AuthorDate: Sat Dec 21 21:47:55 2019 -0800 Commit: Michael Forney CommitDate: Thu Mar 5 00:45:44 2020 -0800 chmod: Remove -HLP flags, and ignore symlinks during traversal These flags are non-POSIX and not useful since the mode of symlinks is not used for anything. This prevents a failure when a dangling symlink is encountered during a recursive chmod. diff --git a/chmod.1 b/chmod.1 index 5ca1ce1..9139351 100644 --- a/chmod.1 +++ b/chmod.1 @@ -1,4 +1,4 @@ -.Dd 2015-10-08 +.Dd 2019-12-21 .Dt CHMOD 1 .Os sbase .Sh NAME @@ -6,10 +6,7 @@ .Nd change file modes .Sh SYNOPSIS .Nm -.Oo -.Fl R -.Op Fl H | L | P -.Oc +.Op Fl R .Ar mode .Ar file ... .Sh DESCRIPTION @@ -58,19 +55,13 @@ read | write | execute | setuid and setgid | sticky .It X execute, if directory or at least one execute bit is already set .El +.Pp +Symbolic links are followed if they are passed as operands, and ignored +if they are encountered during directory traversal. .Sh OPTIONS .Bl -tag -width Ds .It Fl R Change modes recursively. -.It Fl H -Dereference -.Ar file -if it is a symbolic link. -.It Fl L -Dereference all symbolic links. -.It Fl P -Preserve symbolic links. -This is the default. .El .Sh SEE ALSO .Xr chgrp 1 , diff --git a/chmod.c b/chmod.c index 512a7ea..7b9afe8 100644 --- a/chmod.c +++ b/chmod.c @@ -14,7 +14,7 @@ chmodr(const char *path, struct stat *st, void *data, struct recursor *r) mode_t m; m = parsemode(modestr, st->st_mode, mask); - if (chmod(path, m) < 0) { + if (!S_ISLNK(st->st_mode) && chmod(path, m) < 0) { weprintf("chmod %s:", path); ret = 1; } else if (S_ISDIR(st->st_mode)) { @@ -25,14 +25,14 @@ chmodr(const char *path, struct stat *st, void *data, struct recursor *r) static void usage(void) { - eprintf("usage: %s [-R [-H | -L | -P]] mode file ...\n", argv0); + eprintf("usage: %s [-R] mode file ...\n", argv0); } int main(int argc, char *argv[]) { struct recursor r = { .fn = chmodr, .hist = NULL, .depth = 0, .maxdepth = 1, - .follow = 'P', .flags = DIRFIRST }; + .follow = 'H', .flags = DIRFIRST }; size_t i; argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0; @@ -45,11 +45,6 @@ main(int argc, char *argv[]) case 'R': r.maxdepth = 0; break; - case 'H': - case 'L': - case 'P': - r.follow = (*argv)[i]; - break; case 'r': case 'w': case 'x': case 'X': case 's': case 't': /* -[rwxXst] are valid modes, so we're done */ if (i == 1)
[hackers] [sbase] libutil/recurse: Use a single path buffer, and directory fd || Michael Forney
commit edbcc223ea9ef9c3f039352f787af0644d816ee7 Author: Michael Forney AuthorDate: Sun Dec 22 13:53:46 2019 -0800 Commit: Michael Forney CommitDate: Thu Mar 5 00:45:53 2020 -0800 libutil/recurse: Use a single path buffer, and directory fd This way, we don't use PATH_MAX bytes on the stack per path component, and don't have to keep copying the complete path around. diff --git a/chgrp.c b/chgrp.c index 04b2dd0..d336c88 100644 --- a/chgrp.c +++ b/chgrp.c @@ -14,18 +14,17 @@ static gid_t gid = -1; static int ret = 0; static void -chgrp(const char *path, struct stat *st, void *data, struct recursor *r) +chgrp(int dirfd, const char *name, struct stat *st, void *data, struct recursor *r) { int flags = 0; if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) flags |= AT_SYMLINK_NOFOLLOW; - - if (fchownat(AT_FDCWD, path, -1, gid, flags) < 0) { - weprintf("chown %s:", path); + if (fchownat(dirfd, name, -1, gid, flags) < 0) { + weprintf("chown %s:", r->path); ret = 1; } else if (S_ISDIR(st->st_mode)) { - recurse(path, NULL, r); + recurse(dirfd, name, NULL, r); } } @@ -71,7 +70,7 @@ main(int argc, char *argv[]) } for (argc--, argv++; *argv; argc--, argv++) - recurse(*argv, NULL, ); + recurse(AT_FDCWD, *argv, NULL, ); return ret || recurse_status; } diff --git a/chmod.c b/chmod.c index 7b9afe8..554959f 100644 --- a/chmod.c +++ b/chmod.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#include #include #include "fs.h" @@ -9,16 +10,16 @@ static mode_t mask= 0; static intret = 0; static void -chmodr(const char *path, struct stat *st, void *data, struct recursor *r) +chmodr(int dirfd, const char *name, struct stat *st, void *data, struct recursor *r) { mode_t m; m = parsemode(modestr, st->st_mode, mask); - if (!S_ISLNK(st->st_mode) && chmod(path, m) < 0) { - weprintf("chmod %s:", path); + if (!S_ISLNK(st->st_mode) && fchmodat(dirfd, name, m, 0) < 0) { + weprintf("chmod %s:", r->path); ret = 1; } else if (S_ISDIR(st->st_mode)) { - recurse(path, NULL, r); + recurse(dirfd, name, NULL, r); } } @@ -71,7 +72,7 @@ done: usage(); for (--argc, ++argv; *argv; argc--, argv++) - recurse(*argv, NULL, ); + recurse(AT_FDCWD, *argv, NULL, ); return ret || recurse_status; } diff --git a/chown.c b/chown.c index dcd4914..3aaedef 100644 --- a/chown.c +++ b/chown.c @@ -17,18 +17,18 @@ static gid_t gid = -1; static int ret = 0; static void -chownpwgr(const char *path, struct stat *st, void *data, struct recursor *r) +chownpwgr(int dirfd, const char *name, struct stat *st, void *data, struct recursor *r) { int flags = 0; if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) flags |= AT_SYMLINK_NOFOLLOW; - if (fchownat(AT_FDCWD, path, uid, gid, flags) < 0) { - weprintf("chown %s:", path); + if (fchownat(dirfd, name, uid, gid, flags) < 0) { + weprintf("chown %s:", r->path); ret = 1; } else if (S_ISDIR(st->st_mode)) { - recurse(path, NULL, r); + recurse(dirfd, name, NULL, r); } } @@ -99,7 +99,7 @@ main(int argc, char *argv[]) usage(); for (argc--, argv++; *argv; argc--, argv++) - recurse(*argv, NULL, ); + recurse(AT_FDCWD, *argv, NULL, ); return ret || recurse_status; } diff --git a/du.c b/du.c index 4ceac66..fa6a8d6 100644 --- a/du.c +++ b/du.c @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -35,19 +36,19 @@ nblks(blkcnt_t blocks) } static void -du(const char *path, struct stat *st, void *data, struct recursor *r) +du(int dirfd, const char *path, struct stat *st, void *data, struct recursor *r) { off_t *total = data, subtotal; subtotal = nblks(st->st_blocks); if (S_ISDIR(st->st_mode)) - recurse(path, , r); + recurse(dirfd, path, , r); *total += subtotal; if (!r->depth) - printpath(*total, path); + printpath(*total, r->path); else if (!sflag && r->depth <= maxdepth && (S_ISDIR(st->st_mode) || aflag)) - printpath(subtotal, path); + printpath(subtotal, r->path); } static void @@ -104,11 +105,11 @@ main(int argc, char *argv[]) blksize = 1024; if (!argc) { - recurse(".", , ); + recurse(AT_FDCWD, ".", , ); } else { for (;
[hackers] [sbase] Use *at functions with appropriate flags instead of lstat/lchown || Michael Forney
commit 039b54aa510ddc32b9430bb89b98cb8937ac33c3 Author: Michael Forney AuthorDate: Fri Nov 1 20:43:32 2019 -0700 Commit: Michael Forney CommitDate: Thu Mar 5 00:45:53 2020 -0800 Use *at functions with appropriate flags instead of lstat/lchown diff --git a/chgrp.c b/chgrp.c index 960ed2c..04b2dd0 100644 --- a/chgrp.c +++ b/chgrp.c @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -15,19 +16,13 @@ static int ret = 0; static void chgrp(const char *path, struct stat *st, void *data, struct recursor *r) { - char *chownf_name; - int (*chownf)(const char *, uid_t, gid_t); + int flags = 0; - if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) { - chownf_name = "lchown"; - chownf = lchown; - } else { - chownf_name = "chown"; - chownf = chown; - } + if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) + flags |= AT_SYMLINK_NOFOLLOW; - if (chownf(path, -1, gid) < 0) { - weprintf("%s %s:", chownf_name, path); + if (fchownat(AT_FDCWD, path, -1, gid, flags) < 0) { + weprintf("chown %s:", path); ret = 1; } else if (S_ISDIR(st->st_mode)) { recurse(path, NULL, r); diff --git a/chown.c b/chown.c index c517acf..dcd4914 100644 --- a/chown.c +++ b/chown.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include +#include #include #include #include @@ -18,19 +19,13 @@ static int ret = 0; static void chownpwgr(const char *path, struct stat *st, void *data, struct recursor *r) { - char *chownf_name; - int (*chownf)(const char *, uid_t, gid_t); + int flags = 0; - if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) { - chownf_name = "lchown"; - chownf = lchown; - } else { - chownf_name = "chown"; - chownf = chown; - } + if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) + flags |= AT_SYMLINK_NOFOLLOW; - if (chownf(path, uid, gid) < 0) { - weprintf("%s %s:", chownf_name, path); + if (fchownat(AT_FDCWD, path, uid, gid, flags) < 0) { + weprintf("chown %s:", path); ret = 1; } else if (S_ISDIR(st->st_mode)) { recurse(path, NULL, r); diff --git a/libutil/cp.c b/libutil/cp.c index bb85c14..23275ac 100644 --- a/libutil/cp.c +++ b/libutil/cp.c @@ -26,24 +26,18 @@ int cp(const char *s1, const char *s2, int depth) { DIR *dp; - int f1, f2; + int f1, f2, flags = 0; struct dirent *d; struct stat st; struct timespec times[2]; ssize_t r; - int (*statf)(const char *, struct stat *); - char target[PATH_MAX], ns1[PATH_MAX], ns2[PATH_MAX], *statf_name; + char target[PATH_MAX], ns1[PATH_MAX], ns2[PATH_MAX]; - if (cp_follow == 'P' || (cp_follow == 'H' && depth)) { - statf_name = "lstat"; - statf = lstat; - } else { - statf_name = "stat"; - statf = stat; - } + if (cp_follow == 'P' || (cp_follow == 'H' && depth)) + flags |= AT_SYMLINK_NOFOLLOW; - if (statf(s1, ) < 0) { - weprintf("%s %s:", statf_name, s1); + if (fstatat(AT_FDCWD, s1, , flags) < 0) { + weprintf("stat %s:", s1); cp_status = 1; return 0; } diff --git a/libutil/recurse.c b/libutil/recurse.c index 487faac..e150fb9 100644 --- a/libutil/recurse.c +++ b/libutil/recurse.c @@ -1,6 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include #include +#include #include #include #include @@ -21,20 +22,15 @@ recurse(const char *path, void *data, struct recursor *r) struct history *new, *h; struct stat st, dst; DIR *dp; - int (*statf)(const char *, struct stat *); - char subpath[PATH_MAX], *statf_name; + char subpath[PATH_MAX]; + int flags = 0; - if (r->follow == 'P' || (r->follow == 'H' && r->depth)) { - statf_name = "lstat"; - statf = lstat; - } else { - statf_name = "stat"; - statf = stat; - } + if (r->follow == 'P' || (r->follow == 'H' && r->depth)) + flags |= AT_SYMLINK_NOFOLLOW; - if (statf(path, ) < 0) { + if (fstatat(AT_FDCWD, path, , flags) < 0) { if (!(r->flags & SILENT)) { - weprintf("%s %s:", statf_name, path); + weprintf("stat %s:", path); recurse_status = 1; } return;
[hackers] [sbase] *sum: Ignore -b and -t flags || Michael Forney
commit fa2f0e09c301f75a25e75a144c308d9adbebfa6a Author: Michael Forney AuthorDate: Sun Dec 22 11:53:35 2019 -0800 Commit: Michael Forney CommitDate: Thu Mar 5 00:45:53 2020 -0800 *sum: Ignore -b and -t flags diff --git a/md5sum.c b/md5sum.c index 86fb40f..224b20e 100644 --- a/md5sum.c +++ b/md5sum.c @@ -28,6 +28,10 @@ main(int argc, char *argv[]) uint8_t md[MD5_DIGEST_LENGTH]; ARGBEGIN { + case 'b': + case 't': + /* ignore */ + break; case 'c': cryptfunc = cryptcheck; break; diff --git a/sha1sum.c b/sha1sum.c index 4f3ae77..cc8dcae 100644 --- a/sha1sum.c +++ b/sha1sum.c @@ -27,6 +27,10 @@ main(int argc, char *argv[]) uint8_t md[SHA1_DIGEST_LENGTH]; ARGBEGIN { + case 'b': + case 't': + /* ignore */ + break; case 'c': cryptfunc = cryptcheck; break; diff --git a/sha224sum.c b/sha224sum.c index 5c4a6cb..e9a10cf 100644 --- a/sha224sum.c +++ b/sha224sum.c @@ -27,6 +27,10 @@ main(int argc, char *argv[]) uint8_t md[SHA224_DIGEST_LENGTH]; ARGBEGIN { + case 'b': + case 't': + /* ignore */ + break; case 'c': cryptfunc = cryptcheck; break; diff --git a/sha256sum.c b/sha256sum.c index d863539..686c70f 100644 --- a/sha256sum.c +++ b/sha256sum.c @@ -27,6 +27,10 @@ main(int argc, char *argv[]) uint8_t md[SHA256_DIGEST_LENGTH]; ARGBEGIN { + case 'b': + case 't': + /* ignore */ + break; case 'c': cryptfunc = cryptcheck; break; diff --git a/sha384sum.c b/sha384sum.c index f975b61..c76947e 100644 --- a/sha384sum.c +++ b/sha384sum.c @@ -27,6 +27,10 @@ main(int argc, char *argv[]) uint8_t md[SHA384_DIGEST_LENGTH]; ARGBEGIN { + case 'b': + case 't': + /* ignore */ + break; case 'c': cryptfunc = cryptcheck; break; diff --git a/sha512-224sum.c b/sha512-224sum.c index 6e4a9d6..53f2e62 100644 --- a/sha512-224sum.c +++ b/sha512-224sum.c @@ -27,6 +27,10 @@ main(int argc, char *argv[]) uint8_t md[SHA512_224_DIGEST_LENGTH]; ARGBEGIN { + case 'b': + case 't': + /* ignore */ + break; case 'c': cryptfunc = cryptcheck; break; diff --git a/sha512-256sum.c b/sha512-256sum.c index c2d582e..ea556b8 100644 --- a/sha512-256sum.c +++ b/sha512-256sum.c @@ -27,6 +27,10 @@ main(int argc, char *argv[]) uint8_t md[SHA512_256_DIGEST_LENGTH]; ARGBEGIN { + case 'b': + case 't': + /* ignore */ + break; case 'c': cryptfunc = cryptcheck; break; diff --git a/sha512sum.c b/sha512sum.c index 65a0c2c..a76e685 100644 --- a/sha512sum.c +++ b/sha512sum.c @@ -27,6 +27,10 @@ main(int argc, char *argv[]) uint8_t md[SHA512_DIGEST_LENGTH]; ARGBEGIN { + case 'b': + case 't': + /* ignore */ + break; case 'c': cryptfunc = cryptcheck; break;
Re: [hackers] [PATCH][sbase] paste: Allow null delim
Hello all, > Looking at POSIX, I see that `-d '\0'` must be supported, `-d ""` is > unspecified I don't think so, -d "" is just a list with an empty string. So -d '\0' is equivalent to -d '', '\0' is here to let the user express an empty string in a list, which wouldn't be possible otherwise (like how would one specify empty string in a list like 'abcd'). > and `-d""` is invalid, since paste(1) must follow the > utility syntax guidelines (guideline 7). Not sure what you mean there, -d"" is the concatenation of -d and '', which is standard. Did you quote the correct guideline? “Guideline 7: Option-arguments should not be optional.” here there's an option-argument, that's an empty string.
[hackers] [slcon7] Invitation to the suckless conference 2020
Dear fellow hackers! we are pleased to announce the suckless conference[0] on 2020-09-(17-20) in Bad Liebenzell, Baden-Württemberg, Germany. ### Call for Papers There will be regular talk sessions (in English) this year and we are calling for optional talk proposals of around 10-30 minutes covering either technological or philosophical topics (rants are welcome as well). Each proposal should contain - the name of the author - an abstract written in English - presumably reference links to related ideas or topics and be sent to adm...@suckless.org until 2020-07-30. We don't expect a paper or slide set prior to the conference! If you can not attend on a certain day, please add a note about it so we can fine-tune the schedule accordingly. ### Conference Registration The accommodation fee will be around 170€ and includes everything. It will be due upon reservation confirmation. Please contact us if and why you want to request sponsorship for the accomodation; nobody should be left out for financial reasons. In order to be able to arrange the conference properly, we also kindly ask all of you who want to attend the event to register until 2020-08-01 by sending a mail to adm...@suckless.org with your name and clear message that you will definitely attend. Places are limited (!) and secured on a first mail basis. We will inform all successful registrants within 2 weeks after receiving their mail. We also believe that it would be a good idea to arrange your travel already, if you plan to attend. We recommend arrival on 2020-09-17 at noon and departure on 2020-09-20 evening. The closest international airport is Stuttgart, Germany. Bad Liebenzell is a 40 minute trip from Stuttgart airport and well-accessible by train. Members of the suckless.org e.V. are invited to attend our annual Mitgliederversammlung (members meeting) on 2020-09-17 evening at the venue (the invitation and exact location will be sent later). The meeting will be in English. We are looking forward to your talk proposals and registration requests! With best regards Laslo Hunhold [0]: https://suckless.org/conferences/2020/ -- Laslo Hunhold
Re: [hackers] [PATCH][sbase] paste: Allow null delim
Hi Richard, Thanks for the patch. Can you clarify if this change fixes `-d "\0"`, `-d ""` or `-d""`? Looking at POSIX, I see that `-d '\0'` must be supported, `-d ""` is unspecified, and `-d""` is invalid, since paste(1) must follow the utility syntax guidelines (guideline 7). I recently investigated a similar issue to this in tr(1). I think a proper solution would be to add length parameters to utflen and utftorunestr so that they can handle 0-bytes in the strings. On 2020-03-02, Richard Ipsum wrote: > --- > paste.c | 14 ++ > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/paste.c b/paste.c > index b0ac761..0159fe0 100644 > --- a/paste.c > +++ b/paste.c > @@ -53,7 +53,8 @@ nextline: > > for (; efgetrune(, dsc[i].fp, dsc[i].name) ;) { > for (m = last + 1; m < i; m++) > - efputrune(&(delim[m % delimlen]), stdout, > ""); > + if (delim[m % delimlen] != '\0') > + efputrune(&(delim[m % delimlen]), > stdout, ""); > last = i; > if (c == '\n') { > if (i != fdescrlen - 1) > @@ -68,7 +69,8 @@ nextline: > if (i == fdescrlen - 1) > putchar('\n'); > else > - efputrune(, stdout, ""); > + if (d != '\0') > + efputrune(, stdout, ""); > last++; > } > } > @@ -96,7 +98,7 @@ main(int argc, char *argv[]) > seq = 1; > break; > case 'd': > - adelim = EARGF(usage()); > + adelim = ARGF(); I think allowing missing option-argument here breaks POSIX compatibility. > unescape(adelim); > break; > default: > @@ -109,8 +111,12 @@ main(int argc, char *argv[]) > /* populate delimiters */ > /* TODO: fix libutf to accept sizes */ > delim = ereallocarray(NULL, utflen(adelim) + 1, sizeof(*delim)); > - if (!(delimlen = utftorunestr(adelim, delim))) > + if (*adelim == '\0') { > + delimlen = 1; > + *delim = '\0'; > + } else if (!(delimlen = utftorunestr(adelim, delim))) { > usage(); > + } > > /* populate file list */ > dsc = ereallocarray(NULL, argc, sizeof(*dsc)); > -- > 2.25.1