diff options
Diffstat (limited to 'usr/src')
23 files changed, 915 insertions, 530 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version index 32d625d23a..656a8a3d08 100644 --- a/usr/src/boot/Makefile.version +++ b/usr/src/boot/Makefile.version @@ -34,4 +34,4 @@ LOADER_VERSION = 1.1 # Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes. # The version is processed from left to right, the version number can only # be increased. -BOOT_VERSION = $(LOADER_VERSION)-2021.03.07.1 +BOOT_VERSION = $(LOADER_VERSION)-2021.03.16.1 diff --git a/usr/src/boot/sys/boot/common/gfx_fb.c b/usr/src/boot/sys/boot/common/gfx_fb.c index 6331a28ab7..09875a85f1 100644 --- a/usr/src/boot/sys/boot/common/gfx_fb.c +++ b/usr/src/boot/sys/boot/common/gfx_fb.c @@ -1727,6 +1727,113 @@ gfx_fb_putimage(png_t *png, uint32_t ux1, uint32_t uy1, uint32_t ux2, return (0); } +/* Return w^2 + h^2 or 0, if the dimensions are unknown */ +static unsigned +edid_diagonal_squared(void) +{ + unsigned w, h; + + if (edid_info == NULL) + return (0); + + w = edid_info->display.max_horizontal_image_size; + h = edid_info->display.max_vertical_image_size; + + /* If either one is 0, we have aspect ratio, not size */ + if (w == 0 || h == 0) + return (0); + + /* + * some monitors encode the aspect ratio instead of the physical size. + */ + if ((w == 16 && h == 9) || (w == 16 && h == 10) || + (w == 4 && h == 3) || (w == 5 && h == 4)) + return (0); + + /* + * translate cm to inch, note we scale by 100 here. + */ + w = w * 100 / 254; + h = h * 100 / 254; + + /* Return w^2 + h^2 */ + return (w * w + h * h); +} + +/* + * calculate pixels per inch. + */ +static unsigned +gfx_get_ppi(void) +{ + unsigned dp, di; + + di = edid_diagonal_squared(); + if (di == 0) + return (0); + + dp = gfx_fb.framebuffer_common.framebuffer_width * + gfx_fb.framebuffer_common.framebuffer_width + + gfx_fb.framebuffer_common.framebuffer_height * + gfx_fb.framebuffer_common.framebuffer_height; + + return (isqrt(dp / di)); +} + +/* + * Calculate font size from density independent pixels (dp): + * ((16dp * ppi) / 160) * display_factor. + * Here we are using fixed constants: 1dp == 160 ppi and + * display_factor 2. + * + * We are rounding font size up and are searching for font which is + * not smaller than calculated size value. + */ +bitmap_data_t * +gfx_get_font(void) +{ + unsigned ppi, size; + bitmap_data_t *font = NULL; + struct fontlist *fl, *next; + + /* Text mode is not supported here. */ + if (gfx_fb.framebuffer_common.framebuffer_type == + MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT) + return (NULL); + + ppi = gfx_get_ppi(); + if (ppi == 0) + return (NULL); + + /* + * We will search for 16dp font. + * We are using scale up by 10 for roundup. + */ + size = (16 * ppi * 10) / 160; + /* Apply display factor 2. */ + size = roundup(size * 2, 10) / 10; + + STAILQ_FOREACH(fl, &fonts, font_next) { + next = STAILQ_NEXT(fl, font_next); + /* + * If this is last font or, if next font is smaller, + * we have our font. Make sure, it actually is loaded. + */ + if (next == NULL || next->font_data->height < size) { + font = fl->font_data; + if (font->font == NULL || + fl->font_flags == FONT_RELOAD) { + if (fl->font_load != NULL && + fl->font_name != NULL) + font = fl->font_load(fl->font_name); + } + break; + } + } + + return (font); +} + static int load_mapping(int fd, struct font *fp, int n) { diff --git a/usr/src/boot/sys/boot/common/gfx_fb.h b/usr/src/boot/sys/boot/common/gfx_fb.h index 3fb7fcc3af..8d20dcf162 100644 --- a/usr/src/boot/sys/boot/common/gfx_fb.h +++ b/usr/src/boot/sys/boot/common/gfx_fb.h @@ -95,6 +95,8 @@ struct vesa_edid_info { uint8_t checksum; } __packed; +extern struct vesa_edid_info *edid_info; + #define STD_TIMINGS 8 #define DET_TIMINGS 4 diff --git a/usr/src/boot/sys/boot/efi/loader/framebuffer.c b/usr/src/boot/sys/boot/efi/loader/framebuffer.c index d638d136ac..bd86ea3e43 100644 --- a/usr/src/boot/sys/boot/efi/loader/framebuffer.c +++ b/usr/src/boot/sys/boot/efi/loader/framebuffer.c @@ -31,6 +31,7 @@ #include <stand.h> #include <bootstrap.h> #include <sys/endian.h> +#include <sys/param.h> #include <sys/font.h> #include <sys/consplat.h> #include <sys/limits.h> @@ -51,11 +52,13 @@ EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; static EFI_GUID pciio_guid = EFI_PCI_IO_PROTOCOL_GUID; EFI_GUID uga_guid = EFI_UGA_DRAW_PROTOCOL_GUID; static EFI_GUID active_edid_guid = EFI_EDID_ACTIVE_PROTOCOL_GUID; +static EFI_GUID discovered_edid_guid = EFI_EDID_DISCOVERED_PROTOCOL_GUID; +static EFI_HANDLE gop_handle; /* Saved initial GOP mode. */ static uint32_t default_mode = UINT32_MAX; /* Cached EDID. */ -static struct vesa_edid_info *edid_info; +struct vesa_edid_info *edid_info = NULL; static uint32_t gop_default_mode(void); static int efifb_set_mode(EFI_GRAPHICS_OUTPUT *, uint_t); @@ -450,7 +453,7 @@ efifb_from_uga(struct efi_fb *efifb, EFI_UGA_DRAW_PROTOCOL *uga) * Fetch EDID info. Caller must free the buffer. */ static struct vesa_edid_info * -efifb_gop_get_edid(EFI_HANDLE gop) +efifb_gop_get_edid(EFI_HANDLE h) { const uint8_t magic[] = EDID_MAGIC; EFI_EDID_ACTIVE_PROTOCOL *edid; @@ -460,22 +463,25 @@ efifb_gop_get_edid(EFI_HANDLE gop) size_t size; guid = &active_edid_guid; - status = OpenProtocolByHandle(gop, guid, (void **)&edid); - if (status != EFI_SUCCESS) - return (NULL); + status = BS->OpenProtocol(h, guid, (void **)&edid, IH, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (status != EFI_SUCCESS || + edid->SizeOfEdid == 0) { + guid = &discovered_edid_guid; + status = BS->OpenProtocol(h, guid, (void **)&edid, IH, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (status != EFI_SUCCESS || + edid->SizeOfEdid == 0) + return (NULL); + } - size = sizeof (*edid_infop); - if (size < edid->SizeOfEdid) - size = edid->SizeOfEdid; + size = MAX(sizeof (*edid_infop), edid->SizeOfEdid); edid_infop = calloc(1, size); - if (edid_infop == NULL) { - status = BS->CloseProtocol(gop, guid, IH, NULL); + if (edid_infop == NULL) return (NULL); - } memcpy(edid_infop, edid->Edid, edid->SizeOfEdid); - status = BS->CloseProtocol(gop, guid, IH, NULL); /* Validate EDID */ if (memcmp(edid_infop, magic, sizeof (magic)) != 0) @@ -493,11 +499,10 @@ error: static bool efifb_get_edid(edid_res_list_t *res) { - extern EFI_GRAPHICS_OUTPUT *gop; bool rv = false; if (edid_info == NULL) - edid_info = efifb_gop_get_edid(gop); + edid_info = efifb_gop_get_edid(gop_handle); if (edid_info != NULL) rv = gfx_get_edid_resolution(edid_info, res); @@ -508,7 +513,7 @@ efifb_get_edid(edid_res_list_t *res) int efi_find_framebuffer(struct efi_fb *efifb) { - EFI_HANDLE h, *hlist; + EFI_HANDLE *hlist; UINTN nhandles, i, hsize; extern EFI_GRAPHICS_OUTPUT *gop; extern EFI_UGA_DRAW_PROTOCOL *uga; @@ -538,18 +543,18 @@ efi_find_framebuffer(struct efi_fb *efifb) /* * Search for ConOut protocol, if not found, use first handle. */ - h = *hlist; + gop_handle = *hlist; for (i = 0; i < nhandles; i++) { void *dummy = NULL; status = OpenProtocolByHandle(hlist[i], &conout_guid, &dummy); if (status == EFI_SUCCESS) { - h = hlist[i]; + gop_handle = hlist[i]; break; } } - status = OpenProtocolByHandle(h, &gop_guid, (void **)&gop); + status = OpenProtocolByHandle(gop_handle, &gop_guid, (void **)&gop); free(hlist); if (status == EFI_SUCCESS) { diff --git a/usr/src/boot/sys/boot/i386/libi386/vbe.c b/usr/src/boot/sys/boot/i386/libi386/vbe.c index c48427f5f4..a0514aebec 100644 --- a/usr/src/boot/sys/boot/i386/libi386/vbe.c +++ b/usr/src/boot/sys/boot/i386/libi386/vbe.c @@ -49,6 +49,7 @@ static struct modeinfoblock *vbe_mode = (struct modeinfoblock *)&vbestate.vbe_mode_info; static uint16_t *vbe_mode_list; static size_t vbe_mode_list_size; +struct vesa_edid_info *edid_info = NULL; multiboot_color_t *cmap; /* The default VGA color palette format is 6 bits per primary color. */ int palette_format = 6; @@ -573,34 +574,40 @@ vbe_dump_mode(int modenum, struct modeinfoblock *mi) static bool vbe_get_edid(edid_res_list_t *res) { - struct vesa_edid_info *edid_info; + struct vesa_edid_info *edidp; const uint8_t magic[] = EDID_MAGIC; int ddc_caps; bool ret = false; + if (edid_info != NULL) + return (gfx_get_edid_resolution(edid_info, res)); + ddc_caps = biosvbe_ddc_caps(); if (ddc_caps == 0) { return (ret); } - edid_info = bio_alloc(sizeof (*edid_info)); - if (edid_info == NULL) + edidp = bio_alloc(sizeof (*edidp)); + if (edidp == NULL) return (ret); - memset(edid_info, 0, sizeof (*edid_info)); + memset(edidp, 0, sizeof (*edidp)); - if (VBE_ERROR(biosvbe_ddc_read_edid(0, edid_info))) + if (VBE_ERROR(biosvbe_ddc_read_edid(0, edidp))) goto done; - if (memcmp(edid_info, magic, sizeof (magic)) != 0) + if (memcmp(edidp, magic, sizeof (magic)) != 0) goto done; /* Unknown EDID version. */ - if (edid_info->header.version != 1) + if (edidp->header.version != 1) goto done; - ret = gfx_get_edid_resolution(edid_info, res); + ret = gfx_get_edid_resolution(edidp, res); + edid_info = malloc(sizeof (*edid_info)); + if (edid_info != NULL) + memcpy(edid_info, edidp, sizeof (*edid_info)); done: - bio_free(edid_info, sizeof (*edid_info)); + bio_free(edidp, sizeof (*edidp)); return (ret); } diff --git a/usr/src/cmd/ast/libshell/Makefile.demo b/usr/src/cmd/ast/libshell/Makefile.demo index e1a81f07c2..ebddf0e6cc 100644 --- a/usr/src/cmd/ast/libshell/Makefile.demo +++ b/usr/src/cmd/ast/libshell/Makefile.demo @@ -116,6 +116,7 @@ DF_TESTS= \ DF_XTESTS= \ tests/README.tests \ + tests/illumos_4149_builtin_head.sh \ tests/illumos_13434_chunked_heredoc.sh \ tests/sun_solaris_array_default_datatype.sh \ tests/sun_solaris_builtin_poll.sh \ diff --git a/usr/src/cmd/ast/libshell/common/tests/illumos_4149_builtin_head.sh b/usr/src/cmd/ast/libshell/common/tests/illumos_4149_builtin_head.sh new file mode 100644 index 0000000000..a146d3fb2e --- /dev/null +++ b/usr/src/cmd/ast/libshell/common/tests/illumos_4149_builtin_head.sh @@ -0,0 +1,125 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2021 OmniOS Community Edition (OmniOSce) Association. +# + +# +# Test whether the builtin head command properly handles files which do +# not have a trailing newline. +# + +# test setup +function err_exit +{ + print -u2 -n "\t" + print -u2 -r ${Command}[$1]: "${@:2}" + (( Errors++ )) +} +alias err_exit='err_exit $LINENO' + +set -o nounset +Command=${0##*/} +integer Errors=0 + +builtin head tail + +t1=`mktemp` +t2=`mktemp` +t3=`mktemp` +if [[ ! -f "$t1" || ! -f "$t2" || ! -f "$t3" ]]; then + # Don't use the global err _ exit function as the test harness uses + # calls to that to compute the number of tests present in this file. + echo "Could not create temporary files" + rm -f "$t1" "$t2" "$t3" + exit 1 +fi + +for f in test{0..4%02d}; do + echo $f +done | tee $t1 > $t2 +printf "nonewline" >> $t2 +printf "nonewline" >> $t3 + +# Standard file, five lines, with trailing newline + +[[ $(head -1 $t1) == 'test00' ]] || \ + err_exit "Shell head -1 standard file" + +[[ $(head -2 $t1) == $'test00\ntest01' ]] || \ + err_exit "Shell head -2 standard file" + +[[ $(head -s 2 -n2 $t1) == $'test02\ntest03' ]] || \ + err_exit "Shell head -s 2 -n 2 standard file" + +[[ $(head -5 $t1) == $'test00\ntest01\ntest02\ntest03\ntest04' ]] || \ + err_exit "Shell head -5 standard file" + +[[ $(head -10 $t1) == $'test00\ntest01\ntest02\ntest03\ntest04' ]] || \ + err_exit "Shell head -10 standard file" + +[[ $(tail -1 $t1) == 'test04' ]] || \ + err_exit "Shell tail -1 standard file" + +[[ $(tail -2 $t1) == $'test03\ntest04' ]] || \ + err_exit "Shell tail -2 standard file" + +[[ $(tail -10 $t1) == $'test00\ntest01\ntest02\ntest03\ntest04' ]] || \ + err_exit "Shell tail -10 standard file" + +# File with a single line, no trailing newline + +[[ $(head -1 $t3) == 'nonewline' ]] || \ + err_exit "Shell head -1 one-line file" + +[[ $(head -2 $t3) == 'nonewline' ]] || \ + err_exit "Shell head -2 one-line file" + +[[ $(tail -1 $t3) == 'nonewline' ]] || \ + err_exit "Shell tail -1 one-line file" + +[[ $(tail -2 $t3) == 'nonewline' ]] || \ + err_exit "Shell tail -2 one-line file" + +# File with six lines, no trailing newline + +[[ $(head -1 $t2) == "test00" ]] || \ + err_exit "Shell head -1 six-line file" + +[[ $(head -2 $t2) == $'test00\ntest01' ]] || \ + err_exit "Shell head -2 six-line file" + +[[ $(head -s 2 -n2 $t2) == $'test02\ntest03' ]] || \ + err_exit "Shell head -s 2 -n 2 six-line file" + +[[ $(head -5 $t2) == $'test00\ntest01\ntest02\ntest03\ntest04' ]] || \ + err_exit "Shell head -5 six-line file" + +[[ $(head -6 $t2) == $'test00\ntest01\ntest02\ntest03\ntest04\nnonewline' ]] \ + || err_exit "Shell head -6 six-line file" + +[[ $(head -10 $t2) == $'test00\ntest01\ntest02\ntest03\ntest04\nnonewline' ]] \ + || err_exit "Shell head -10 six-line file" + +[[ $(tail -1 $t2) == 'nonewline' ]] || \ + err_exit "Shell tail -1 six-line file" + +[[ $(tail -2 $t2) == $'test04\nnonewline' ]] || \ + err_exit "Shell tail -2 six-line file" + +[[ $(tail -10 $t2) == $'test00\ntest01\ntest02\ntest03\ntest04\nnonewline' ]] \ + || err_exit "Shell tail -10 six-line file" + +rm -f "$t1" "$t2" "$t3" + +# tests done +exit $Errors diff --git a/usr/src/cmd/availdevs/Makefile b/usr/src/cmd/availdevs/Makefile index dfa150f6c9..faa9a3011e 100644 --- a/usr/src/cmd/availdevs/Makefile +++ b/usr/src/cmd/availdevs/Makefile @@ -32,13 +32,8 @@ ROOTCMDDIR= $(ROOTLIB)/zfs INCS += -I$(ADJUNCT_PROTO)/usr/include/libxml2 -# -# There is no lint library for libxml2, so we need to avoid linking against -# it during lint, as well as turning off the warnings lint would generate. -# -LDLIBS += -lzfs_jni -lnvpair -lzfs +LDLIBS += -lzfs_jni -lnvpair -lzfs -lxml2 NATIVE_LIBS += libxml2.so -all install := LDLIBS += -lxml2 CPPFLAGS += $(INCS) -D_LARGEFILE64_SOURCE=1 -D_REENTRANT $(NOT_RELEASE_BUILD) CPPFLAGS += -DDEBUG diff --git a/usr/src/common/font/font.c b/usr/src/common/font/font.c index 35e2e12eca..b3d1041b52 100644 --- a/usr/src/common/font/font.c +++ b/usr/src/common/font/font.c @@ -196,6 +196,12 @@ reset_font_flags(void) } } +__weak_symbol bitmap_data_t * +gfx_get_font(void) +{ + return (NULL); +} + bitmap_data_t * set_font(short *rows, short *cols, short h, short w) { @@ -221,6 +227,9 @@ set_font(short *rows, short *cols, short h, short w) } } + if (font == NULL) + font = gfx_get_font(); + if (font != NULL) { *rows = (height - BORDER_PIXELS) / font->height; *cols = (width - BORDER_PIXELS) / font->width; diff --git a/usr/src/contrib/ast/src/cmd/ksh93/bltins/print.c b/usr/src/contrib/ast/src/cmd/ksh93/bltins/print.c index 99a7bcd00f..93e4ac3ebd 100644 --- a/usr/src/contrib/ast/src/cmd/ksh93/bltins/print.c +++ b/usr/src/contrib/ast/src/cmd/ksh93/bltins/print.c @@ -198,6 +198,8 @@ int b_print(int argc, char *argv[], Shbltin_t *context) argv++; goto skip; } + argv++; + goto printf; } while((n = optget(argv,options))) switch(n) { @@ -273,6 +275,7 @@ int b_print(int argc, char *argv[], Shbltin_t *context) break; } argv += opt_info.index; +printf: if(error_info.errors || (argc<0 && !(format = *argv++))) errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0)); if(vflag && format) diff --git a/usr/src/contrib/ast/src/lib/libast/sfio/sfmove.c b/usr/src/contrib/ast/src/lib/libast/sfio/sfmove.c index 9e3965750a..413a977c5c 100644 --- a/usr/src/contrib/ast/src/lib/libast/sfio/sfmove.c +++ b/usr/src/contrib/ast/src/lib/libast/sfio/sfmove.c @@ -1,7 +1,7 @@ /*********************************************************************** * * * This software is part of the ast package * -* Copyright (c) 1985-2011 AT&T Intellectual Property * +* Copyright (c) 1985-2013 AT&T Intellectual Property * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * @@ -14,9 +14,9 @@ * AT&T Research * * Florham Park NJ * * * -* Glenn Fowler <gsf@research.att.com> * -* David Korn <dgk@research.att.com> * -* Phong Vo <kpv@research.att.com> * +* Glenn Fowler <glenn.s.fowler@gmail.com> * +* David Korn <dgkorn@gmail.com> * +* Phong Vo <phongvo@gmail.com> * * * ***********************************************************************/ #include "sfhdr.h" @@ -113,7 +113,11 @@ reg int rc; /* record separator */ /* try reading a block of data */ direct = 0; - if((r = fr->endb - (next = fr->next)) <= 0) + if(fr->rsrv && (r = -fr->rsrv->slen) > 0) + { fr->rsrv->slen = 0; + next = fr->rsrv->data; + } + else if((r = fr->endb - (next = fr->next)) <= 0) { /* amount of data remained to be read */ if((w = n > MAX_SSIZE ? MAX_SSIZE : (ssize_t)n) < 0) { if(fr->extent < 0) diff --git a/usr/src/contrib/ast/src/lib/libcmd/chgrp.c b/usr/src/contrib/ast/src/lib/libcmd/chgrp.c index 680e46294e..98bd5dde80 100644 --- a/usr/src/contrib/ast/src/lib/libcmd/chgrp.c +++ b/usr/src/contrib/ast/src/lib/libcmd/chgrp.c @@ -134,7 +134,13 @@ typedef struct Map_s /* uid/gid map */ Key_t to; /* map to these */ } Map_t; +/* + * libast's struid() has the peculiar feature that it returns -1 in response + * to not finding a UID for a name on the first call, and -2 for subsequent + * calls for the same string. + */ #define NOID (-1) +#define STILLNOID (-2) #define OPT_CHOWN 0x0001 /* chown */ #define OPT_FORCE 0x0002 /* ignore errors */ @@ -180,7 +186,7 @@ getids(register char* s, char** e, Key_t* key, int options) n = (int)strtol(s, &z, 0); if (*z || !(options & OPT_NUMERIC)) { - if ((m = struid(s)) != NOID) + if ((m = struid(s)) != NOID && m != STILLNOID) n = m; else if (*z) error(ERROR_exit(1), "%s: unknown user", s); @@ -200,7 +206,7 @@ getids(register char* s, char** e, Key_t* key, int options) n = (int)strtol(s, &z, 0); if (*z || !(options & OPT_NUMERIC)) { - if ((m = strgid(s)) != NOID) + if ((m = strgid(s)) != NOID && m != STILLNOID) n = m; else if (*z) error(ERROR_exit(1), "%s: unknown group", s); diff --git a/usr/src/contrib/ast/src/lib/libcmd/head.c b/usr/src/contrib/ast/src/lib/libcmd/head.c index 426e7db80f..7f39aef72b 100644 --- a/usr/src/contrib/ast/src/lib/libcmd/head.c +++ b/usr/src/contrib/ast/src/lib/libcmd/head.c @@ -1,7 +1,7 @@ /*********************************************************************** * * * This software is part of the ast package * -* Copyright (c) 1992-2012 AT&T Intellectual Property * +* Copyright (c) 1992-2013 AT&T Intellectual Property * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * @@ -14,8 +14,8 @@ * AT&T Research * * Florham Park NJ * * * -* Glenn Fowler <gsf@research.att.com> * -* David Korn <dgk@research.att.com> * +* Glenn Fowler <glenn.s.fowler@gmail.com> * +* David Korn <dgkorn@gmail.com> * * * ***********************************************************************/ #pragma prototyped @@ -27,7 +27,7 @@ */ static const char usage[] = -"[-n?\n@(#)$Id: head (AT&T Research) 2012-05-31 $\n]" +"[-n?\n@(#)$Id: head (AT&T Research) 2013-09-19 $\n]" USAGE_LICENSE "[+NAME?head - output beginning portion of one or more files ]" "[+DESCRIPTION?\bhead\b copies one or more input files to standard " @@ -77,6 +77,7 @@ b_head(int argc, register char** argv, Shbltin_t* context) register off_t keep = 10; register off_t skip = 0; register int delim = '\n'; + off_t moved; int header = 1; char* format = (char*)header_fmt+1; @@ -138,9 +139,16 @@ b_head(int argc, register char** argv, Shbltin_t* context) sfprintf(sfstdout, format, cp); format = (char*)header_fmt; if (skip > 0) - sfmove(fp, NiL, skip, delim); - if (sfmove(fp, sfstdout, keep, delim) < 0 && !ERROR_PIPE(errno) && errno != EINTR) + { + if ((moved = sfmove(fp, NiL, skip, delim)) < 0 && !ERROR_PIPE(errno) && errno != EINTR) + error(ERROR_system(0), "%s: skip error", cp); + if (delim >= 0 && moved < skip) + goto next; + } + if ((moved = sfmove(fp, sfstdout, keep, delim)) < 0 && !ERROR_PIPE(errno) && errno != EINTR || + delim >= 0 && moved < keep && sfmove(fp, sfstdout, SF_UNBOUND, -1) < 0 && !ERROR_PIPE(errno) && errno != EINTR) error(ERROR_system(0), "%s: read error", cp); + next: if (fp != sfstdin) sfclose(fp); } while (cp = *argv++); diff --git a/usr/src/contrib/ast/src/lib/libcmd/tail.c b/usr/src/contrib/ast/src/lib/libcmd/tail.c index ce52f9f3d6..4f078a7709 100644 --- a/usr/src/contrib/ast/src/lib/libcmd/tail.c +++ b/usr/src/contrib/ast/src/lib/libcmd/tail.c @@ -1,7 +1,7 @@ /*********************************************************************** * * * This software is part of the ast package * -* Copyright (c) 1992-2012 AT&T Intellectual Property * +* Copyright (c) 1992-2013 AT&T Intellectual Property * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * @@ -14,8 +14,8 @@ * AT&T Research * * Florham Park NJ * * * -* Glenn Fowler <gsf@research.att.com> * -* David Korn <dgk@research.att.com> * +* Glenn Fowler <glenn.s.fowler@gmail.com> * +* David Korn <dgkorn@gmail.com> * * * ***********************************************************************/ #pragma prototyped @@ -28,7 +28,7 @@ */ static const char usage[] = -"+[-?\n@(#)$Id: tail (AT&T Research) 2012-06-19 $\n]" +"+[-?\n@(#)$Id: tail (AT&T Research) 2013-09-19 $\n]" USAGE_LICENSE "[+NAME?tail - output trailing portion of one or more files ]" "[+DESCRIPTION?\btail\b copies one or more input files to standard output " @@ -159,8 +159,10 @@ tailpos(register Sfio_t* fp, register Sfoff_t number, int delim) register Sfoff_t last; register char* s; register char* t; + int incomplete; struct stat st; + error(-1, "AHA#%d tail number=%I*d", __LINE__, sizeof(number), number); last = sfsize(fp); if ((first = sfseek(fp, (Sfoff_t)0, SEEK_CUR)) < 0) return last || fstat(sffileno(fp), &st) || st.st_size || FIFO(st.st_mode) ? -1 : 0; @@ -170,6 +172,7 @@ tailpos(register Sfio_t* fp, register Sfoff_t number, int delim) return first; return offset; } + incomplete = 1; for (;;) { if ((offset = last - SF_BUFSIZE) < first) @@ -179,6 +182,15 @@ tailpos(register Sfio_t* fp, register Sfoff_t number, int delim) if (!(s = sfreserve(fp, n, SF_LOCKR))) return -1; t = s + n; + if (incomplete) + { + if (t > s && *(t - 1) != delim && number-- <= 0) + { + sfread(fp, s, 0); + return offset + (t - s); + } + incomplete = 0; + } while (t > s) if (*--t == delim && number-- <= 0) { @@ -280,6 +292,7 @@ init(Tail_t* tp, Sfoff_t number, int delim, int flags, const char** format) return -1; } sfset(tp->sp, SF_SHARE, 0); + error(-1, "AHA#%d offset=%I*d number=%I*d", __LINE__, sizeof(offset), offset, sizeof(number), number); if (offset) { if (number < 0 || !number && (flags & POSITIVE)) @@ -410,6 +423,7 @@ b_tail(int argc, char** argv, Shbltin_t* context) char* t; char* r; char* file; + Sfoff_t moved; Sfoff_t offset; Sfoff_t number = DEFAULT; unsigned long timeout = 0; @@ -424,7 +438,7 @@ b_tail(int argc, char** argv, Shbltin_t* context) Tail_t* files; Tv_t tv; - cmdinit(argc, argv, context, ERROR_CATALOG, 0); + cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY); for (;;) { switch (n = optget(argv, usage)) @@ -639,7 +653,7 @@ b_tail(int argc, char** argv, Shbltin_t* context) { if (n) n = 0; - else if (sh_checksig(context) || tvsleep(&tv, NiL)) + else if (sh_checksig(context) || tvsleep(&tv, NiL) && sh_checksig(context)) { error_info.errors++; break; @@ -686,11 +700,13 @@ b_tail(int argc, char** argv, Shbltin_t* context) { i = 3; while (--i && stat(fp->name, &st)) - if (sh_checksig(context) || tvsleep(&tv, NiL)) + if (sh_checksig(context)) { error_info.errors++; goto done; } + else + tvsleep(&tv, NiL); if (i && (fp->dev != st.st_dev || fp->ino != st.st_ino) && !init(fp, 0, 0, flags, &format)) { if (!(flags & SILENT)) @@ -746,8 +762,8 @@ b_tail(int argc, char** argv, Shbltin_t* context) if (number < 0 || !number && (flags & POSITIVE)) { sfset(ip, SF_SHARE, 1); - if (number < -1) - sfmove(ip, NiL, -number - 1, delim); + if (number < -1 && (moved = sfmove(ip, NiL, -(number + 1), delim)) >= 0 && delim >= 0 && moved < -(number + 1)) + (void)sfgetr(ip, delim, SF_LASTR); if (flags & REVERSE) rev_line(ip, sfstdout, sfseek(ip, (Sfoff_t)0, SEEK_CUR)); else diff --git a/usr/src/lib/libc/port/gen/getcwd.c b/usr/src/lib/libc/port/gen/getcwd.c index d832d798d7..62f12e027e 100644 --- a/usr/src/lib/libc/port/gen/getcwd.c +++ b/usr/src/lib/libc/port/gen/getcwd.c @@ -22,10 +22,9 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * getcwd() returns the pathname of the current working directory. * On error, a NULL pointer is returned and errno is set. @@ -34,16 +33,63 @@ #pragma weak _getcwd = getcwd #include "lint.h" +#include <sys/param.h> #include <sys/syscall.h> #include <sys/types.h> #include <errno.h> +#include <limits.h> #include <stdlib.h> +#include <string.h> +#include <unistd.h> char * getcwd(char *pathname, size_t size) { int alloc = 0; + if (size == 0 && pathname == NULL) { + /* + * If no size was provided, start with a buffer that should + * accommodate any normal path and, if it is not big enough, + * keep doubling it to try and make enough space. + * + * Any non-global zone path is longer when observed from the + * global zone, and some filesystems, including ZFS, support + * paths much longer than MAXPATHLEN/_PC_PATH_MAX. + * + * To protect against unbounded memory usage, cap to 128KiB. + * This is an arbitrary limit which is far bigger than the + * length of any practical path on the system. + */ + if ((size = pathconf(".", _PC_PATH_MAX)) == -1) + size = MAXPATHLEN; + + while (size <= 0x20000) { + if ((pathname = reallocf(pathname, size)) == NULL) { + errno = ENOMEM; + return (NULL); + } + if (syscall(SYS_getcwd, pathname, size) == 0) { + char *ret; + + /* + * Shrink the buffer to the length actually + * required to hold the final path. + */ + ret = realloc(pathname, strlen(pathname) + 1); + if (ret == NULL) + return (pathname); + + return (ret); + } + if (errno != ERANGE) + break; + size <<= 1; + } + free(pathname); + return (NULL); + } + if (size == 0) { errno = EINVAL; return (NULL); diff --git a/usr/src/man/man2/chown.2 b/usr/src/man/man2/chown.2 index 72c42a6a5f..cd0605dd23 100644 --- a/usr/src/man/man2/chown.2 +++ b/usr/src/man/man2/chown.2 @@ -1,319 +1,340 @@ '\" te .\" Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 1989 AT&T +.\" Copyright 2021 Oxide Computer Company .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH CHOWN 2 "Mar 2, 2021" -.SH NAME -chown, lchown, fchown, fchownat \- change owner and group of a file -.SH SYNOPSIS -.nf -#include <unistd.h> -#include <sys/types.h> - -\fBint\fR \fBchown\fR(\fBconst char *\fR\fIpath\fR, \fBuid_t\fR \fIowner\fR, \fBgid_t\fR \fIgroup\fR); -.fi - -.LP -.nf -\fBint\fR \fBlchown\fR(\fBconst char *\fR\fIpath\fR, \fBuid_t\fR \fIowner\fR, \fBgid_t\fR \fIgroup\fR); -.fi - -.LP -.nf -\fBint\fR \fBfchown\fR(\fBint\fR \fIfildes\fR, \fBuid_t\fR \fIowner\fR, \fBgid_t\fR \fIgroup\fR); -.fi - -.LP -.nf -\fBint\fR \fBfchownat\fR(\fBint\fR \fIfildes\fR, \fBconst char *\fR\fIpath\fR, \fBuid_t\fR \fIowner\fR, - \fBgid_t\fR \fIgroup\fR, \fBint\fR \fIflag\fR); -.fi - -.SH DESCRIPTION -The \fBchown()\fR function sets the owner \fBID\fR and group \fBID\fR of the -file specified by \fIpath\fR or referenced by the open file descriptor -\fIfildes\fR to \fIowner\fR and \fIgroup\fR respectively. If \fIowner\fR or -\fIgroup\fR is specified as \(mi1, \fBchown()\fR does not change the -corresponding \fBID\fR of the file. -.sp -.LP -The \fBlchown()\fR function sets the owner \fBID\fR and group \fBID\fR of the -named file in the same manner as \fBchown()\fR, unless the named file is a -symbolic link. In this case, \fBlchown()\fR changes the ownership of the -symbolic link file itself, while \fBchown()\fR changes the ownership of the -file or directory to which the symbolic link refers. -.sp -.LP -The \fBfchownat()\fR function sets the owner ID and group ID of the named file -in the same manner as \fBchown()\fR. If, however, the \fIpath\fR argument is -relative, the path is resolved relative to the \fIfildes\fR argument rather -than the current working directory. If the \fIfildes\fR argument has the -special value \fBAT_FDCWD\fR, the path resolution reverts back to current -working directory relative. If the \fIflag\fR argument is set to \fBAT_SYMLINK_NOFOLLOW\fR, -the function behaves like \fBlchown()\fR with respect to symbolic links. If the -\fIpath\fR argument is absolute, the \fIfildes\fR argument is ignored. If the -\fIpath\fR argument is a null pointer, the function behaves like -\fBfchown()\fR. -.sp -.LP -If \fBchown()\fR, \fBlchown()\fR, \fBfchown()\fR, or \fBfchownat()\fR is -invoked by a process that does not have {\fBPRIV_FILE_SETID\fR} asserted in its -effective set, the set-user-ID and set-group-ID bits of the file mode, -\fBS_ISUID\fR and \fBS_ISGID\fR respectively, are cleared (see -\fBchmod\fR(2)). Additional restrictions apply when changing the ownership to -uid 0. -.sp -.LP +.Dd March 13, 2021 +.Dt CHOWN 2 +.Os +.Sh NAME +.Nm chown , +.Nm lchown , +.Nm fchown , +.Nm fchownat +.Nd change owner and group of a file +.Sh SYNOPSIS +.In unistd.h +.In sys/types.h +.Ft int +.Fo chown +.Fa "const char *path" +.Fa "uid_t owner" +.Fa "gid_t group" +.Fc +.Ft int +.Fo lchown +.Fa "const char *path" +.Fa "uid_t owner" +.Fa "gid_t group" +.Fc +.Ft int +.Fo fchown +.Fa "int fildes" +.Fa "uid_t owner" +.Fa "gid_t group" +.Fc +.Ft int +.Fo fchownat +.Fa "int fildes" +.Fa "const char *path" +.Fa "uid_t owner" +.Fa "gid_t group" +.Fa "int flag" +.Fc +.Sh DESCRIPTION +The +.Fn chown +and +.Fn fchown +functions set the owner +.Sy ID +and group +.Sy ID +of the file specified by +.Fa path +or referenced by the open file descriptor +.Fa fildes +to +.Fa owner +and +.Fa group +respectively. +If +.Fa owner +or +.Fa group +is specified as -1, +.Fn chown +and +.Fn fchown +do not change the corresponding +.Sy ID +of the file. +.Pp +The +.Fn lchown +function sets the owner +.Sy ID +and group +.Sy ID +of the named file in the same manner as +.Fn chown , +unless the named file is a symbolic link. +In this case, +.Fn lchown +changes the ownership of the symbolic link file itself, while +.Fn chown +changes the ownership of the file or directory to which the symbolic link +refers. +.Pp +The +.Fn fchownat +function sets the owner ID and group ID of the named file +in the same manner as +.Fn chown . +If, however, the +.Fa path +argument is relative +.Po +does not start with a +.Qq / +.Pc , +the path is resolved relative to the +.Fa fildes +argument rather than the current working directory. +If the +.Fa fildes +argument has the special value +.Dv AT_FDCWD , +the path resolution reverts back to current working directory relative. +If the +.Fa flag +argument is set to +.Dv AT_SYMLINK_NOFOLLOW , +the function behaves like +.Fn lchown +with respect to symbolic links. +If the +.Fa path +argument is absolute, the +.Fa fildes +argument is ignored. +If the +.Fa path +argument is a null pointer, the function behaves like +.Fn fchown . +.Pp +If +.Fn chown , +.Fn lchown , +.Fn fchown , +or +.Fn fchownat +is invoked by a process that does not have +.Brq Dv PRIV_FILE_SETID +asserted in its effective set, the set-user-ID and set-group-ID bits of the +file mode, +.Dv S_ISUID +and +.Dv S_ISGID +respectively, are cleared +.Po +see +.Xr chmod 2 +.Pc . +Additional restrictions apply when changing the ownership to uid 0. +.Pp The operating system defines several privileges to override restrictions on the -\fBchown()\fR family of functions. When the {\fBPRIV_FILE_CHOWN\fR} privilege -is asserted in the effective set of the current process, there are no +.Fn chown +family of functions. +When the +.Brq Dv PRIV_FILE_CHOWN +privilege is asserted in the effective set of the current process, there are no restrictions except in the special circumstances of changing ownership to or -from uid 0. When the {\fBPRIV_FILE_CHOWN_SELF\fR} privilege is asserted, -ownership changes are restricted to the files of which the ownership matches -the effective user ID of the current process. If neither privilege is asserted -in the effective set of the calling process, ownership changes are limited to -changes of the group of the file to the list of supplementary group IDs and the -effective group ID. -.sp -.LP +from uid 0. +When the +.Brq Dv PRIV_FILE_CHOWN_SELF +privilege is asserted, ownership changes are restricted to the files of which +the ownership matches the effective user ID of the current process. +If neither privilege is asserted in the effective set of the calling process, +ownership changes are limited to changes of the group of the file to the list of +supplementary group IDs and the effective group ID. +.Pp The operating system provides a configuration option, -{\fB_POSIX_CHOWN_RESTRICTED\fR}, to control the default behavior of processes -and the behavior of the NFS server. If {\fB_POSIX_CHOWN_RESTRICTED\fR} is not -in effect, the privilege {\fBPRIV_FILE_CHOWN_SELF\fR} is asserted in the -inheritable set of all processes unless overridden by \fBpolicy.conf\fR(4) or -\fBuser_attr\fR(4). To set this configuration option, include the following -line in \fB/etc/system\fR: -.sp -.LP +.Brq Dv _POSIX_CHOWN_RESTRICTED , +to control the default behavior of processes and the behavior of the NFS server. +If +.Brq Dv B_POSIX_CHOWN_RESTRICTED +is not in effect, the privilege +.Brq PRIV_FILE_CHOWN_SELF +is asserted in the inheritable set of all processes unless overridden by +.Xr policy.conf 4 +or +.Xr user_attr 4 . +To set this configuration option, include the following +line in +.Pa /etc/system : +.Bd -literal -offset indent set rstchown = 1 -.sp -.LP -To disable this option, include the following line in \fB/etc/system\fR: -.sp -.LP +.Ed +.Pp +To disable this option, include the following line in +.Pa /etc/system : +.Bd -literal -offset indent set rstchown = 0 -.sp -.LP -See \fBsystem\fR(4) and \fBfpathconf\fR(2). -.sp -.LP -Upon successful completion, \fBchown()\fR, \fBfchown()\fR and \fBlchown()\fR -mark for update the \fBst_ctime\fR field of the file. -.SH RETURN VALUES -Upon successful completion, \fB0\fR is returned. Otherwise, \fB\(mi1\fR is -returned, the owner and group of the named file remain unchanged, and -\fBerrno\fR is set to indicate the error. -.SH ERRORS +.Ed +.Pp +See +.Xr system 4 +and +.Xr fpathconf 2 . +.Pp +Upon successful completion, +.Fn chown , +.Fn fchown , +.Fn lchown , +and +.Fn fchownat +mark for update the +.Fa st_ctime +field of the file. +.Sh RETURN VALUES +Upon successful completion, +.Sy 0 +is returned. +Otherwise, +.Sy -1 +is returned, the owner and group of the named file remain unchanged, and +.Va errno +is set to indicate the error. +.Sh ERRORS All of these functions will fail if: -.sp -.ne 2 -.na -\fB\fBEPERM\fR\fR -.ad -.RS 9n +.Bl -tag -width Er +.It Er EPERM The effective user ID does not match the owner of the file and the -{\fBPRIV_FILE_CHOWN\fR} privilege is not asserted in the effective set of the -calling process, or the {\fBPRIV_FILE_CHOWN_SELF\fR} privilege is not asserted -in the effective set of the calling process. -.RE - -.sp -.LP -The \fBchown()\fR, \fBlchown()\fR, and \fBfchownat()\fR functions will fail if: -.sp -.ne 2 -.na -\fB\fBEACCES\fR\fR -.ad -.RS 16n -Search permission is denied on a component of the path prefix of \fIpath\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBEFAULT\fR\fR -.ad -.RS 16n -The \fIpath\fR argument points to an illegal address and for \fBfchownat()\fR, -the file descriptor has the value \fBAT_FDCWD\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBEINTR\fR\fR -.ad -.RS 16n -A signal was caught during the execution of the \fBchown()\fR or \fBlchown()\fR +.Brq Dv PRIV_FILE_CHOWN +privilege is not asserted in the effective set of the calling process, or the +.Brq Dv PRIV_FILE_CHOWN_SELF +privilege is not asserted in the effective set of the calling process. +.El +.Pp +The +.Fn chown , +.Fn lchown , +and +.Fn fchownat +functions will fail if: +.Bl -tag -width Er +.It Er EACCES +Search permission is denied on a component of the path prefix of +.Fa path . +.It Er EFAULT +The +.Fa path +argument points to an illegal address and for +.Fn fchownat , +the file descriptor has the value +.Dv AT_FDCWD . +.It Er EINTR +A signal was caught during the execution of the +.Fn chown +or +.Fn lchown function. -.RE - -.sp -.ne 2 -.na -\fB\fBEINVAL\fR\fR -.ad -.RS 16n -The \fIgroup\fR or \fIowner\fR argument is out of range. -.RE - -.sp -.ne 2 -.na -\fB\fBEIO\fR\fR -.ad -.RS 16n +.It Er EINVAL +The +.Fa group +or +.Fa owner +argument is out of range. +.It Er EIO An I/O error occurred while reading from or writing to the file system. -.RE - -.sp -.ne 2 -.na -\fB\fBELOOP\fR\fR -.ad -.RS 16n -Too many symbolic links were encountered in translating \fIpath\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBENAMETOOLONG\fR\fR -.ad -.RS 16n -The length of the \fIpath\fR argument exceeds {\fIPATH_MAX\fR}, or the length -of a \fIpath\fR component exceeds {\fINAME_MAX\fR} while -{\fB_POSIX_NO_TRUNC\fR} is in effect. -.RE - -.sp -.ne 2 -.na -\fB\fBENOLINK\fR\fR -.ad -.RS 16n -The \fIpath\fR argument points to a remote machine and the link to that machine -is no longer active. -.RE - -.sp -.ne 2 -.na -\fB\fBENOENT\fR\fR -.ad -.RS 16n -Either a component of the path prefix or the file referred to by \fIpath\fR +.It Er ELOOP +Too many symbolic links were encountered in translating +.Fa path . +.It Er ENAMETOOLONG +The length of the +.Fa path +argument exceeds +.Brq Dv PATH_MAX , +or the length of a +.Fa path +component exceeds +.Brq Dv NAME_MAX +while +.Brq Dv _POSIX_NO_TRUNC +is in effect. +.It Er ENOLINK +The +.Fa path +argument points to a remote machine and the link to that machine is no longer +active. +.It Er ENOENT +Either a component of the path prefix or the file referred to by +.Fa path does not exist or is a null pathname. -.RE - -.sp -.ne 2 -.na -\fB\fBENOTDIR\fR\fR -.ad -.RS 16n -A component of the path prefix of \fIpath\fR is not a directory, or the path -supplied to \fBfchownat()\fR is relative and the file descriptor provided does -not refer to a valid directory. -.RE - -.sp -.ne 2 -.na -\fB\fBEROFS\fR\fR -.ad -.RS 16n -The named file resides on a read-only file system. -.RE - -.sp -.LP -The \fBfchown()\fR and \fBfchownat()\fR functions will fail if: -.sp -.ne 2 -.na -\fB\fBEBADF\fR\fR -.ad -.RS 11n -For \fBfchown()\fR the \fIfildes\fR argument is not an open file descriptor -and. -.sp -For \fBfchownat()\fR, the \fIpath\fR argument is not absolute and the -\fIfildes\fR argument is not \fBAT_FDCWD\fR or an open file descriptor. -.RE - -.sp -.ne 2 -.na -\fB\fBEIO\fR\fR -.ad -.RS 11n +.It Er ENOTDIR +A component of the path prefix of +.Fa path +is not a directory, or the path supplied to +.Fn fchownat +is relative and the file descriptor provided does not refer to a valid +directory. +.It Er EROFS +The named file resides on a read-only file system. +.El +.Pp +The +.Fn chown +and +.Fn fchownat +functions will fail if: +.Bl -tag -width Er +.It Er EBADF +For +.Fn fchown , +the +.Fa fildes +argument is not an open file descriptor. +.Pp +For +.Fn fchownat , +the +.Fa path +argument is not absolute and the fildes argument is neither +.Dv AT_FDCWD , +nor an open file descriptor. +.It Er EIO An I/O error occurred while reading from or writing to the file system. -.RE - -.sp -.ne 2 -.na -\fB\fBEINTR\fR\fR -.ad -.RS 11n +.It Er EINTR A signal was caught during execution of the function. -.RE - -.sp -.ne 2 -.na -\fB\fBENOLINK\fR\fR -.ad -.RS 11n -The \fIfildes\fR argument points to a remote machine and the link to that -machine is no longer active. -.RE - -.sp -.ne 2 -.na -\fB\fBEINVAL\fR\fR -.ad -.RS 11n -The \fIgroup\fR or \fIowner\fR argument is out of range. -.RE - -.sp -.ne 2 -.na -\fB\fBEROFS\fR\fR -.ad -.RS 11n -The named file referred to by \fIfildes\fR resides on a read-only file system. -.RE - -.SH ATTRIBUTES -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability See below. -_ -MT-Level See below. -.TE - -.sp -.LP -The \fBchown()\fR, \fBfchown()\fR, and \fBlchown()\fR functions are Standard. -The \fBfchownat()\fR function is Evolving. -.sp -.LP -The \fBchown()\fR and \fBfchownat()\fR functions are Async-Signal-Safe. -.SH SEE ALSO -\fBchgrp\fR(1), \fBchown\fR(1), \fBchmod\fR(2), \fBfpathconf\fR(2), -\fBsystem\fR(4), \fBattributes\fR(5), \fBstandards\fR(5) +.It Er ENOLINK +The +.Fa fildes +argument points to a remote machine and the link to that machine is no longer +active. +.It Er EINVAL +The +.Fa group +or +.Fa owner +argument is out of range. +.It Er EROFS +The named file referred to by +.Fa fildes +resides on a read-only file system. +.El +.Sh INTERFACE STABILITY +.Sy Committed +.Sh MT-LEVEL +.Sy Async-Signal-Safe +.Sh SEE ALSO +.Xr chgrp 1 , +.Xr chown 1 , +.Xr chmod 2 , +.Xr fpathconf 2 , +.Xr system 4 , +.Xr attributes 5 , +.Xr standards 5 diff --git a/usr/src/man/man3c/getcwd.3c b/usr/src/man/man3c/getcwd.3c index f1114bc6dd..ba27b7f9bb 100644 --- a/usr/src/man/man3c/getcwd.3c +++ b/usr/src/man/man3c/getcwd.3c @@ -43,110 +43,98 @@ .\" Copyright 1989 AT&T .\" Copyright (c) 2001, The IEEE and The Open Group. All Rights Reserved. .\" Portions Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved. +.\" Copyright 2021 OmniOS Community Edition (OmniOSce) Association. .\" -.TH GETCWD 3C "Oct 18, 2004" -.SH NAME -getcwd \- get pathname of current working directory -.SH SYNOPSIS -.LP -.nf -#include <unistd.h> - -\fBchar *\fR\fBgetcwd\fR(\fBchar *\fR\fIbuf\fR, \fBsize_t\fR \fIsize\fR); -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBgetcwd()\fR function places an absolute pathname of the current working -directory in the array pointed to by \fIbuf\fR, and returns \fIbuf\fR. The -pathname copied to the array contains no components that are symbolic links. -The \fIsize\fR argument is the size in bytes of the character array pointed to -by \fIbuf\fR and must be at least one greater than the length of the pathname -to be returned. -.sp -.LP -If \fIbuf\fR is not a null pointer, the pathname is stored in the space pointed -to by \fIbuf\fR. -.sp -.LP -If \fIbuf\fR is a null pointer, \fBgetcwd()\fR obtains \fIsize\fR bytes of -space using \fBmalloc\fR(3C). The pointer returned by \fBgetcwd()\fR can be -used as the argument in a subsequent call to \fBfree()\fR. -.SH RETURN VALUES -.sp -.LP -Upon successful completion, \fBgetcwd()\fR returns the \fIbuf\fR argument. If -\fIbuf\fR is an invalid destination buffer address, \fINULL\fR is returned and -\fBerrno\fR is set to \fBEFAULT\fR. Otherwise, a null pointer is returned and -\fBerrno\fR is set to indicate the error. -.SH ERRORS -.sp -.LP -The \fBgetcwd()\fR function will fail if: -.sp -.ne 2 -.na -\fB\fBEFAULT\fR\fR -.ad -.RS 10n -The \fIbuf\fR argument is an invalid destination buffer address. -.RE - -.sp -.ne 2 -.na -\fB\fBEINVAL\fR\fR -.ad -.RS 10n -The \fIsize\fR argument is equal to 0. -.RE - -.sp -.ne 2 -.na -\fB\fBERANGE\fR\fR -.ad -.RS 10n -The \fIsize\fR argument is greater than 0 and less than the length of the -pathname plus 1. -.RE - -.sp -.LP -The \fBgetcwd()\fR function may fail if: -.sp -.ne 2 -.na -\fB\fBEACCES\fR\fR -.ad -.RS 10n -A parent directory cannot be read to get its name. -.RE - -.sp -.ne 2 -.na -\fB\fBENOMEM\fR\fR -.ad -.RS 10n -Insufficient storage space is available. -.RE - -.SH EXAMPLES -.LP -\fBExample 1 \fRDetermine the absolute pathname of the current working +.Dd February 27, 2021 +.Dt GETCWD 3C +.Os +.Sh NAME +.Nm getcwd +.Nd get pathname of current working directory +.Sh SYNOPSIS +.In unistd.h +.Ft "char *" +.Fo getcwd +.Fa "char *buf" +.Fa "size_t size" +.Fc +.Sh DESCRIPTION +The +.Fn getcwd +function returns a pointer to a buffer containing the absolute pathname of the +current working directory. +The returned pathname contains no components that are symbolic links. +.Pp +When +.Fa buf +is not +.Dv NULL , +the absolute pathname will be written into +.Fa buf +and +.Fa size +represents the length in bytes of +.Fa buf . +If the length of the pathname and nul terminator exceeds +.Fa size , +nothing will be written and +.Fn getcwd +will return +.Dv NULL . +Otherwise, +.Fn getcwd +returns +.Fa buf . +.Pp +When +.Fa buf +is +.Dv NULL +then +.Fn getcwd +will allocate memory in which to store the pathname of the current working directory. -.sp -.LP +If +.Fa size +is non-zero, then +.Fa size +bytes will be allocated. +If the length of the pathname and nul terminator exceeds +.Fa size , +the memory will be freed and +.Fn getcwd +will return +.Dv NULL . +If +.Fa size +is zero, then +.Fn getcwd +will attempt to allocate enough space to hold the pathname. +In both cases, it is the caller's responsibility to free the returned buffer +with the +.Xr free 3C +function. +.Sh RETURN VALUES +Upon successful completion, the +.Fn getcwd +function returns a pointer to a buffer containing the pathname. +Otherwise, +.Dv NULL +is returned and +.Va errno +is set to indicate the error. +.Sh EXAMPLES +.Sy Example 1 +Determine the absolute pathname of the current working directory. +.Pp The following example returns a pointer to an array that holds the absolute -pathname of the current working directory. The pointer is returned in the -\fIptr\fR variable, which points to the \fIbuf\fR array where the pathname is -stored. - -.sp -.in +2 -.nf +pathname of the current working directory. +The pointer is returned in the +.Va ptr +variable, which points to the +.Va buf +array where the pathname is stored. +.Bd -literal -offset Ds #include <stdlib.h> #include <unistd.h> \&... @@ -155,64 +143,75 @@ char *buf; char *ptr; size = pathconf(".", _PC_PATH_MAX); if ((buf = (char *)malloc((size_t)size)) != NULL) - ptr = getcwd(buf, (size_t)size); + ptr = getcwd(buf, (size_t)size); \&... -.fi -.in -2 - -.LP -\fBExample 2 \fRPrint the current working directory. -.sp -.LP +.Ed +.Pp +.Sy Example 2 +Print the current working directory. +.Pp The following example prints the current working directory. - -.sp -.in +2 -.nf -#include <unistd.h> +.Bd -literal -offset Ds #include <stdio.h> +#include <unistd.h> -main(\|) +int +main(void) { - char *cwd; - if ((cwd = getcwd(NULL, 64)) == NULL) { - perror("pwd"); - exit(2); - } - (void)printf("%s\en", cwd); - free(cwd); /* free memory allocated by getcwd() */ - return(0); -} -.fi -.in -2 + char *cwd; -.SH USAGE -.sp -.LP -Applications should exercise care when using \fBchdir\fR(2) in conjunction with -\fBgetcwd()\fR. The current working directory is global to all threads within a -process. If more than one thread calls \fBchdir()\fR to change the working -directory, a subsequent call to \fBgetcwd()\fR could produce unexpected -results. -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability Standard -_ -MT-Level MT-Safe -.TE - -.SH SEE ALSO -.sp -.LP -\fBchdir\fR(2), \fBmalloc\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5) + if ((cwd = getcwd(NULL, 0)) == NULL) { + perror("pwd"); + exit(2); + } + (void)printf("%s\en", cwd); + free(cwd); /* free memory allocated by getcwd() */ + return(0); +} +.Ed +.Sh ERRORS +The +.Fn getcwd +function will fail if: +.Bl -tag -width Er +.It Er EFAULT +The +.Fa buf +argument points to an invalid address. +.It Er EINVAL +The +.Fa buf +argument is not +.Dv NULL +and the +.Fa size +argument is 0. +.It Er ERANGE +The pathname +.Pq including its terminating nul character +is too long to fit into the provided +.Pq or allocated +buffer. +.It Er EACCESS +A parent directory cannot be read to get its name. +.It Er ENOMEM +Insufficient storage space is available. +.El +.Sh USAGE +Applications should exercise care when using +.Xr chdir 2 +in conjunction with +.Fn getcwd . +The current working directory is global to all threads within a process. +If more than one thread calls +.Xr chdir 2 +to change the working directory, a subsequent call to +.Fn getcwd +could produce unexpected results. +.Sh INTERFACE STABILITY +.Sy Committed +.Sh SEE ALSO +.Xr chdir 2 , +.Xr free 3C , +.Xr attributes 5 , +.Xr standards 5 diff --git a/usr/src/pkg/manifests/driver-cpu-sensor.mf b/usr/src/pkg/manifests/driver-cpu-sensor.mf index a9070dd31e..f3fbbbffe0 100644 --- a/usr/src/pkg/manifests/driver-cpu-sensor.mf +++ b/usr/src/pkg/manifests/driver-cpu-sensor.mf @@ -50,7 +50,7 @@ driver name=pchtemp \ alias=pci8086,a231,p \ alias=pci8086,a2b1,p \ alias=pci8086,a379,p -driver name=smntemp alias=smntemp +driver name=smntemp file path=kernel/drv/$(ARCH64)/amdnbtemp group=sys file path=kernel/drv/$(ARCH64)/coretemp group=sys file path=kernel/drv/$(ARCH64)/pchtemp group=sys diff --git a/usr/src/pkg/manifests/driver-storage-ahci.mf b/usr/src/pkg/manifests/driver-storage-ahci.mf index e01b367360..ac63fde808 100644 --- a/usr/src/pkg/manifests/driver-storage-ahci.mf +++ b/usr/src/pkg/manifests/driver-storage-ahci.mf @@ -43,8 +43,17 @@ dir path=kernel/drv/$(ARCH64) group=sys dir path=usr/lib/ahci dir path=usr/share/man dir path=usr/share/man/man7d -driver name=ahci alias=pciclass,010601 class=scsi-self-identifying \ - perms="* 0644 root sys" +# +# In general, we expect ahci devices to use the ahci class code. +# However, there are a handful of Intel controller hubs which will +# advertise a RAID variant that doesn't match the class code, but have +# experimentally (and based on reading between the lines in their +# datasheets) proven to still support AHCI. +# +driver name=ahci class=scsi-self-identifying perms="* 0644 root sys" \ + alias=pci8086,2822,p \ + alias=pci8086,282a,p \ + alias=pciclass,010601 file path=kernel/drv/$(ARCH64)/ahci group=sys file path=usr/lib/ahci/ahciem mode=0555 file path=usr/share/man/man7d/ahci.7d diff --git a/usr/src/pkg/manifests/source-demo-system.mf b/usr/src/pkg/manifests/source-demo-system.mf index b2aaf94cbf..e3415901dc 100644 --- a/usr/src/pkg/manifests/source-demo-system.mf +++ b/usr/src/pkg/manifests/source-demo-system.mf @@ -130,6 +130,7 @@ file path=usr/demo/ksh/tests/glob.sh file path=usr/demo/ksh/tests/grep.sh file path=usr/demo/ksh/tests/heredoc.sh file path=usr/demo/ksh/tests/illumos_13434_chunked_heredoc.sh +file path=usr/demo/ksh/tests/illumos_4149_builtin_head.sh file path=usr/demo/ksh/tests/io.sh file path=usr/demo/ksh/tests/leaks.sh file path=usr/demo/ksh/tests/locale.sh diff --git a/usr/src/uts/common/syscall/getcwd.c b/usr/src/uts/common/syscall/getcwd.c index b0c9b83d8b..4c83278314 100644 --- a/usr/src/uts/common/syscall/getcwd.c +++ b/usr/src/uts/common/syscall/getcwd.c @@ -22,10 +22,9 @@ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/copyops.h> #include <sys/errno.h> #include <sys/kmem.h> @@ -44,31 +43,49 @@ getcwd(char *buf, size_t buflen) size_t kbuflen; /* + * If the buffer cannot accommodate one character and nul terminator, + * it is too small. + */ + if (buflen < 2) + return (set_errno(ERANGE)); + + /* * The user should be able to specify any size buffer, but we don't want * to arbitrarily allocate huge kernel buffers just because the user * requests it. So we'll start with MAXPATHLEN (which should hold any - * normal path), and only increase it if we fail with ERANGE. + * normal path), and only increase it if we fail with + * ERANGE / ENAMETOOLONG. + * + * To protect against unbounded memory usage, cap to kmem_max_cached. + * This is far bigger than the length of any practical path on the + * system, and avoids allocating memory from the kmem_oversized arena. */ kbuflen = MIN(buflen, MAXPATHLEN); - for (;;) { + while (kbuflen <= kmem_max_cached) { kbuf = kmem_alloc(kbuflen, KM_SLEEP); if (((err = dogetcwd(kbuf, kbuflen)) == 0) && - (copyout(kbuf, buf, strlen(kbuf) + 1) != 0)) + (copyout(kbuf, buf, strlen(kbuf) + 1) != 0)) { err = EFAULT; + } kmem_free(kbuf, kbuflen); - if (err == ENAMETOOLONG) { + /* + * dogetcwd() inconsistently returns ERANGE or ENAMETOOLONG + * depending on whether it calls dirtopath() and then whether + * the subsequent operations run out of space whilst + * evaluating a cached vnode path or otherwise. + */ + if (err == ENAMETOOLONG || err == ERANGE) { + /* For some reason, getcwd() uses ERANGE. */ + err = ERANGE; /* * If the user's buffer really was too small, give up. - * For some reason, getcwd() uses ERANGE for this case. */ - if (kbuflen == buflen) { - err = ERANGE; + if (kbuflen == buflen) break; - } kbuflen = MIN(kbuflen * 2, buflen); } else { break; diff --git a/usr/src/uts/intel/io/coretemp/coretemp.c b/usr/src/uts/intel/io/coretemp/coretemp.c index bea8078002..4b4382dd8a 100644 --- a/usr/src/uts/intel/io/coretemp/coretemp.c +++ b/usr/src/uts/intel/io/coretemp/coretemp.c @@ -11,7 +11,7 @@ /* * Copyright 2019, Joyent, Inc. - * Copyright 2020 Oxide Computer Company + * Copyright 2021 Oxide Computer Company */ /* @@ -389,6 +389,9 @@ coretemp_create_sensor(coretemp_t *ct, cmi_hdl_t hdl, uint_t tjmax, "for %s: %d", sensor->cs_name, err); } + ASSERT(MUTEX_HELD(&ct->coretemp_mutex)); + list_insert_tail(&ct->coretemp_sensors, sensor); + return (B_TRUE); err: kmem_free(sensor, sizeof (coretemp_sensor_t)); diff --git a/usr/src/uts/intel/os/driver_aliases b/usr/src/uts/intel/os/driver_aliases index 2ffdd0b03e..15533b7da6 100644 --- a/usr/src/uts/intel/os/driver_aliases +++ b/usr/src/uts/intel/os/driver_aliases @@ -63,6 +63,8 @@ agptarget "pci8086,7120" agptarget "pci8086,7122" agptarget "pci8086,7124" ahci "pciclass,010601" +ahci "pci8086,2822,p" +ahci "pci8086,282a,p" amd64_gart "pci1022,1103" amd8111s "pci1022,7462" amd_iommu "pci1002,5a23" @@ -1418,7 +1420,6 @@ sfxge "pci1924,903" sfxge "pci1924,923" sgen "scsa,08.bfcp" sgen "scsa,08.bvhci" -smntemp "smntemp" smrt "pci103c,1920" smrt "pci103c,1921" smrt "pci103c,1922" |