summaryrefslogtreecommitdiff
path: root/usr.bin/uniq
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2013-09-05 20:18:59 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2013-09-05 20:18:59 +0000
commitd1d015864103b253b3fcb2f72a0da5b0cfeb31b6 (patch)
tree22b131dceb13c3df96da594fbaadb693504797c7 /usr.bin/uniq
parent12d4083451fc39b3e831d4ea0bfa67d3b32cfb54 (diff)
parentb6f49c23a36f329cbf1e7f28078e17fd87f0e245 (diff)
downloadsrc-test-d1d015864103b253b3fcb2f72a0da5b0cfeb31b6.tar.gz
src-test-d1d015864103b253b3fcb2f72a0da5b0cfeb31b6.zip
Merge from head
Notes
Notes: svn path=/projects/bmake/; revision=255263
Diffstat (limited to 'usr.bin/uniq')
-rw-r--r--usr.bin/uniq/uniq.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/usr.bin/uniq/uniq.c b/usr.bin/uniq/uniq.c
index 1077307dab1c1..8e7f40fd14c4c 100644
--- a/usr.bin/uniq/uniq.c
+++ b/usr.bin/uniq/uniq.c
@@ -44,15 +44,20 @@ static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
+#include <sys/capability.h>
+
#include <ctype.h>
#include <err.h>
+#include <errno.h>
#include <limits.h>
#include <locale.h>
+#include <nl_types.h>
#include <stdint.h>
#define _WITH_GETLINE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <termios.h>
#include <unistd.h>
#include <wchar.h>
#include <wctype.h>
@@ -68,6 +73,17 @@ static wchar_t *skip(wchar_t *);
static void obsolete(char *[]);
static void usage(void);
+static void
+strerror_init(void)
+{
+
+ /*
+ * Cache NLS data before entering capability mode.
+ * XXXPJD: There should be strerror_init() and strsignal_init() in libc.
+ */
+ (void)catopen("libc", NL_CAT_LOCALE);
+}
+
int
main (int argc, char *argv[])
{
@@ -77,6 +93,7 @@ main (int argc, char *argv[])
size_t prevbuflen, thisbuflen, b1;
char *prevline, *thisline, *p;
const char *ifn;
+ cap_rights_t rights;
(void) setlocale(LC_ALL, "");
@@ -128,8 +145,33 @@ main (int argc, char *argv[])
ofp = stdout;
if (argc > 0 && strcmp(argv[0], "-") != 0)
ifp = file(ifn = argv[0], "r");
+ cap_rights_init(&rights, CAP_FSTAT, CAP_READ);
+ if (cap_rights_limit(fileno(ifp), &rights) < 0 && errno != ENOSYS)
+ err(1, "unable to limit rights for %s", ifn);
+ cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE);
if (argc > 1)
ofp = file(argv[1], "w");
+ else
+ cap_rights_set(&rights, CAP_IOCTL);
+ if (cap_rights_limit(fileno(ofp), &rights) < 0 && errno != ENOSYS) {
+ err(1, "unable to limit rights for %s",
+ argc > 1 ? argv[1] : "stdout");
+ }
+ if (cap_rights_is_set(&rights, CAP_IOCTL)) {
+ unsigned long cmd;
+
+ cmd = TIOCGETA; /* required by isatty(3) in printf(3) */
+
+ if (cap_ioctls_limit(fileno(ofp), &cmd, 1) < 0 &&
+ errno != ENOSYS) {
+ err(1, "unable to limit ioctls for %s",
+ argc > 1 ? argv[1] : "stdout");
+ }
+ }
+
+ strerror_init();
+ if (cap_enter() < 0 && errno != ENOSYS)
+ err(1, "unable to enter capability mode");
prevbuflen = thisbuflen = 0;
prevline = thisline = NULL;