/* * 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 2017 Nexenta Systems, Inc. All rights reserved. */ #include #include #include #include #include #include #include #include #include extern const char *__progname; int vflag = 0; static int dosattr_set_ro(int fildes, const char *fname) { nvlist_t *nvl = NULL; int err; err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0); if (err != 0) return (err); (void) nvlist_add_boolean_value(nvl, A_READONLY, 1); if (fname == NULL) { err = fsetattr(fildes, XATTR_VIEW_READWRITE, nvl); } else { err = setattrat(fildes, XATTR_VIEW_READWRITE, fname, nvl); } if (err < 0) { err = errno; if (vflag > 1) { (void) fprintf(stderr, "dosattr_set: setattrat (%s), err %d\n", fname, err); } } nvlist_free(nvl); return (err); } void usage(void) { (void) fprintf(stderr, "usage: %s [-v] file\n", __progname); exit(1); } int main(int argc, char **argv) { char *fname; int c, fd, n; while ((c = getopt(argc, argv, "v")) != -1) { switch (c) { case 'v': vflag++; break; case '?': default: usage(); break; } } if (optind + 1 != argc) usage(); fname = argv[optind]; fd = open(fname, O_CREAT | O_RDWR, 0644); if (fd < 0) { perror(fname); exit(1); } if (vflag) (void) fprintf(stderr, "Write 1 (mode 644)\n"); n = write(fd, "mode 644 OK\n", 12); if (n != 12) { (void) fprintf(stderr, "write mode 644, err=%d\n", errno); exit(1); } if (vflag) (void) fprintf(stderr, "Chmod 444\n"); n = fchmod(fd, 0444); if (n < 0) { (void) fprintf(stderr, "chmod 444, err=%d\n", errno); exit(1); } if (vflag) (void) fprintf(stderr, "Write 2 (mode 444)\n"); n = write(fd, "mode 444 OK\n", 12); if (n != 12) { (void) fprintf(stderr, "write mode 444, err=%d\n", errno); exit(1); } if (vflag) (void) fprintf(stderr, "Set DOS R/O\n"); n = dosattr_set_ro(fd, NULL /* fname? */); if (n != 0) { (void) fprintf(stderr, "Set R/O, err=%d\n", n); exit(1); } /* * This fails, but write on an already open handle should succeed * the same as when we've set the mode to 444 after open. */ if (vflag) (void) fprintf(stderr, "Write 3 (DOS R/O)\n"); n = write(fd, "Write DOS RO?\n", 14); if (n != 14) { (void) fprintf(stderr, "write (DOS R/O), err=%d\n", errno); exit(1); } return (0); }