integrate from head@185615
This commit is contained in:
commit
e57c2b130f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/quota64/; revision=185617
@ -15,10 +15,10 @@ are met:
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
|
45
Makefile
45
Makefile
@ -267,6 +267,10 @@ make: .PHONY
|
||||
${MMAKE} all && \
|
||||
${MMAKE} install DESTDIR=${MAKEPATH} BINDIR=
|
||||
|
||||
tinderbox:
|
||||
cd ${.CURDIR} && \
|
||||
DOING_TINDERBOX=YES ${MAKE} ${JFLAG} universe
|
||||
|
||||
#
|
||||
# universe
|
||||
#
|
||||
@ -274,14 +278,24 @@ make: .PHONY
|
||||
# with a reasonable chance of success, regardless of how old your
|
||||
# existing system is.
|
||||
#
|
||||
.if make(universe)
|
||||
.if make(universe) || make(tinderbox)
|
||||
TARGETS?=amd64 arm i386 ia64 pc98 powerpc sparc64 sun4v
|
||||
|
||||
.if defined(DOING_TINDERBOX)
|
||||
FAILFILE=tinderbox.failed
|
||||
MAKEFAIL=tee -a ${FAILFILE}
|
||||
.else
|
||||
MAKEFAIL=cat
|
||||
.endif
|
||||
|
||||
universe: universe_prologue
|
||||
universe_prologue:
|
||||
@echo "--------------------------------------------------------------"
|
||||
@echo ">>> make universe started on ${STARTTIME}"
|
||||
@echo "--------------------------------------------------------------"
|
||||
.if defined(DOING_TINDERBOX)
|
||||
rm -f ${FAILFILE}
|
||||
.endif
|
||||
.for target in ${TARGETS}
|
||||
KERNCONFS!= cd ${.CURDIR}/sys/${target}/conf && \
|
||||
find [A-Z]*[A-Z] -type f -maxdepth 0 \
|
||||
@ -292,22 +306,28 @@ universe: universe_${target}
|
||||
universe_${target}:
|
||||
.if !defined(MAKE_JUST_KERNELS)
|
||||
@echo ">> ${target} started on `LC_ALL=C date`"
|
||||
-cd ${.CURDIR} && ${MAKE} ${JFLAG} buildworld \
|
||||
@(cd ${.CURDIR} && env __MAKE_CONF=/dev/null \
|
||||
${MAKE} ${JFLAG} buildworld \
|
||||
TARGET=${target} \
|
||||
__MAKE_CONF=/dev/null \
|
||||
> _.${target}.buildworld 2>&1
|
||||
> _.${target}.buildworld 2>&1 || \
|
||||
(echo "${target} world failed," \
|
||||
"check _.${target}.buildworld for details" | ${MAKEFAIL}))
|
||||
@echo ">> ${target} buildworld completed on `LC_ALL=C date`"
|
||||
.endif
|
||||
.if exists(${.CURDIR}/sys/${target}/conf/NOTES)
|
||||
-cd ${.CURDIR}/sys/${target}/conf && ${MAKE} LINT \
|
||||
> ${.CURDIR}/_.${target}.makeLINT 2>&1
|
||||
@(cd ${.CURDIR}/sys/${target}/conf && env __MAKE_CONF=/dev/null \
|
||||
${MAKE} LINT > ${.CURDIR}/_.${target}.makeLINT 2>&1 || \
|
||||
(echo "${target} 'make LINT' failed," \
|
||||
"check _.${target}.makeLINT for details"| ${MAKEFAIL}))
|
||||
.endif
|
||||
.for kernel in ${KERNCONFS}
|
||||
-cd ${.CURDIR} && ${MAKE} ${JFLAG} buildkernel \
|
||||
@(cd ${.CURDIR} && env __MAKE_CONF=/dev/null \
|
||||
${MAKE} ${JFLAG} buildkernel \
|
||||
TARGET=${target} \
|
||||
KERNCONF=${kernel} \
|
||||
__MAKE_CONF=/dev/null \
|
||||
> _.${target}.${kernel} 2>&1
|
||||
> _.${target}.${kernel} 2>&1 || \
|
||||
(echo "${target} ${kernel} kernel failed," \
|
||||
"check _.${target}.${kernel} for details"| ${MAKEFAIL}))
|
||||
.endfor
|
||||
@echo ">> ${target} completed on `LC_ALL=C date`"
|
||||
.endfor
|
||||
@ -317,4 +337,11 @@ universe_epilogue:
|
||||
@echo ">>> make universe completed on `LC_ALL=C date`"
|
||||
@echo " (started ${STARTTIME})"
|
||||
@echo "--------------------------------------------------------------"
|
||||
.if defined(DOING_TINDERBOX)
|
||||
@if [ -e ${FAILFILE} ] ; then \
|
||||
echo "Tinderbox failed:" ;\
|
||||
cat ${FAILFILE} ;\
|
||||
exit 1 ;\
|
||||
fi
|
||||
.endif
|
||||
.endif
|
||||
|
@ -505,6 +505,9 @@ distribute32 install32:
|
||||
cd ${.CURDIR}/gnu/lib; ${LIB32IMAKE} ${.TARGET:S/32$//}
|
||||
.if ${MK_CRYPT} != "no"
|
||||
cd ${.CURDIR}/secure/lib; ${LIB32IMAKE} ${.TARGET:S/32$//}
|
||||
.endif
|
||||
.if ${MK_KERBEROS} != "no"
|
||||
cd ${.CURDIR}/kerberos5/lib; ${LIB32IMAKE} ${.TARGET:S/32$//}
|
||||
.endif
|
||||
cd ${.CURDIR}/libexec/rtld-elf; \
|
||||
PROG=ld-elf32.so.1 ${LIB32IMAKE} ${.TARGET:S/32$//}
|
||||
|
@ -14,6 +14,11 @@
|
||||
# The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last.
|
||||
#
|
||||
|
||||
# 20081123: vfs_mountedon.9 removed
|
||||
OLD_FILES+=usr/share/man/man9/vfs_mountedon.9.gz
|
||||
# 20081023: FREE.9 and MALLOC.9 removed
|
||||
OLD_FILES+=usr/share/man/man9/FREE.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/MALLOC.9.gz
|
||||
# 20080928: removal of inaccurate device_ids(9) manual page
|
||||
OLD_FILES+=usr/share/man/man9/device_ids.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/major.9.gz
|
||||
|
32
UPDATING
32
UPDATING
@ -22,6 +22,38 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
|
||||
to maximize performance. (To disable malloc debugging, run
|
||||
ln -s aj /etc/malloc.conf.)
|
||||
|
||||
20081130:
|
||||
__FreeBSD_version 800057 marks the switchover from the
|
||||
binary ath hal to source code. Users must add the line:
|
||||
|
||||
options AH_SUPPORT_AR5416
|
||||
|
||||
to their kernel config files when specifying:
|
||||
|
||||
device ath_hal
|
||||
|
||||
The ath_hal module no longer exists; the code is now compiled
|
||||
together with the driver in the ath module. It is now
|
||||
possible to tailor chip support (i.e. reduce the set of chips
|
||||
and thereby the code size); consult ath_hal(4) for details.
|
||||
|
||||
20081121:
|
||||
__FreeBSD_version 800054 adds memory barriers to
|
||||
<machine/atomic.h>, new interfaces to ifnet to facilitate
|
||||
multiple hardware transmit queues for cards that support
|
||||
them, and a lock-less ring-buffer implementation to
|
||||
enable drivers to more efficiently manage queueing of
|
||||
packets.
|
||||
|
||||
20081117:
|
||||
A new version of ZFS (version 13) has been merged to -HEAD.
|
||||
This version has zpool attribute "listsnapshots" off by
|
||||
default, which means "zfs list" does not show snapshots,
|
||||
and is the same as Solaris behavior.
|
||||
|
||||
20081028:
|
||||
dummynet(4) ABI has changed. ipfw(8) needs to be recompiled.
|
||||
|
||||
20081009:
|
||||
The uhci, ohci, ehci and slhci USB Host controller drivers have
|
||||
been put into separate modules. If you load the usb module
|
||||
|
@ -77,6 +77,17 @@ static void raw_cat(int);
|
||||
static int udom_open(const char *path, int flags);
|
||||
#endif
|
||||
|
||||
/* Memory strategy threshold, in pages: if physmem is larger then this, use a
|
||||
* large buffer */
|
||||
#define PHYSPAGES_THRESHOLD (32*1024)
|
||||
|
||||
/* Maximum buffer size in bytes - do not allow it to grow larger than this */
|
||||
#define BUFSIZE_MAX (2*1024*1024)
|
||||
|
||||
/* Small (default) buffer size in bytes. It's inefficient for this to be
|
||||
* smaller than MAXPHYS */
|
||||
#define BUFSIZE_SMALL (MAXPHYS)
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
@ -247,9 +258,17 @@ raw_cat(int rfd)
|
||||
if (buf == NULL) {
|
||||
if (fstat(wfd, &sbuf))
|
||||
err(1, "%s", filename);
|
||||
bsize = MAX(sbuf.st_blksize, 1024);
|
||||
if (S_ISREG(sbuf.st_mode)) {
|
||||
/* If there's plenty of RAM, use a large copy buffer */
|
||||
if (sysconf(_SC_PHYS_PAGES) > PHYSPAGES_THRESHOLD)
|
||||
bsize = MIN(BUFSIZE_MAX, MAXPHYS*8);
|
||||
else
|
||||
bsize = BUFSIZE_SMALL;
|
||||
} else
|
||||
bsize = MAX(sbuf.st_blksize,
|
||||
(blksize_t)sysconf(_SC_PAGESIZE));
|
||||
if ((buf = malloc(bsize)) == NULL)
|
||||
err(1, "buffer");
|
||||
err(1, "malloc() failure of IO buffer");
|
||||
}
|
||||
while ((nr = read(rfd, buf, bsize)) > 0)
|
||||
for (off = 0; nr; nr -= nw, off += nw)
|
||||
|
@ -69,7 +69,7 @@ static const char *bits_to_string(ces_status_flags, const char *);
|
||||
|
||||
static void find_element(char *, uint16_t *, uint16_t *);
|
||||
static struct changer_element_status *get_element_status
|
||||
(unsigned int, unsigned int);
|
||||
(unsigned int, unsigned int, int);
|
||||
|
||||
static int do_move(const char *, int, char **);
|
||||
static int do_exchange(const char *, int, char **);
|
||||
@ -969,7 +969,8 @@ do_return(const char *cname, int argc, char **argv)
|
||||
++argv; --argc;
|
||||
|
||||
/* Get the status */
|
||||
ces = get_element_status((unsigned int)type, (unsigned int)element);
|
||||
ces = get_element_status((unsigned int)type, (unsigned int)element,
|
||||
CHET_VT == type);
|
||||
|
||||
if (NULL == ces)
|
||||
errx(1, "%s: null element status pointer", cname);
|
||||
@ -1004,7 +1005,7 @@ do_return(const char *cname, int argc, char **argv)
|
||||
* should free() it when done.
|
||||
*/
|
||||
static struct changer_element_status *
|
||||
get_element_status(unsigned int type, unsigned int element)
|
||||
get_element_status(unsigned int type, unsigned int element, int use_voltags)
|
||||
{
|
||||
struct changer_element_status_request cesr;
|
||||
struct changer_element_status *ces;
|
||||
@ -1020,7 +1021,8 @@ get_element_status(unsigned int type, unsigned int element)
|
||||
cesr.cesr_element_type = (uint16_t)type;
|
||||
cesr.cesr_element_base = (uint16_t)element;
|
||||
cesr.cesr_element_count = 1; /* Only this one element */
|
||||
cesr.cesr_flags |= CESR_VOLTAGS; /* Grab voltags as well */
|
||||
if (use_voltags)
|
||||
cesr.cesr_flags |= CESR_VOLTAGS; /* Grab voltags as well */
|
||||
cesr.cesr_element_status = ces;
|
||||
|
||||
if (ioctl(changer_fd, CHIOGSTATUS, (char *)&cesr) == -1) {
|
||||
|
@ -57,10 +57,22 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define cp_pct(x, y) ((y == 0) ? 0 : (int)(100.0 * (x) / (y)))
|
||||
|
||||
/* Memory strategy threshold, in pages: if physmem is larger then this, use a
|
||||
* large buffer */
|
||||
#define PHYSPAGES_THRESHOLD (32*1024)
|
||||
|
||||
/* Maximum buffer size in bytes - do not allow it to grow larger than this */
|
||||
#define BUFSIZE_MAX (2*1024*1024)
|
||||
|
||||
/* Small (default) buffer size in bytes. It's inefficient for this to be
|
||||
* smaller than MAXPHYS */
|
||||
#define BUFSIZE_SMALL (MAXPHYS)
|
||||
|
||||
int
|
||||
copy_file(const FTSENT *entp, int dne)
|
||||
{
|
||||
static char buf[MAXBSIZE];
|
||||
static char *buf = NULL;
|
||||
static size_t bufsize;
|
||||
struct stat *fs;
|
||||
ssize_t wcount;
|
||||
size_t wresid;
|
||||
@ -137,47 +149,60 @@ copy_file(const FTSENT *entp, int dne)
|
||||
* Mmap and write if less than 8M (the limit is so we don't totally
|
||||
* trash memory on big files. This is really a minor hack, but it
|
||||
* wins some CPU back.
|
||||
* Some filesystems, such as smbnetfs, don't support mmap,
|
||||
* so this is a best-effort attempt.
|
||||
*/
|
||||
#ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
|
||||
if (S_ISREG(fs->st_mode) && fs->st_size > 0 &&
|
||||
fs->st_size <= 8 * 1048576) {
|
||||
if ((p = mmap(NULL, (size_t)fs->st_size, PROT_READ,
|
||||
MAP_SHARED, from_fd, (off_t)0)) == MAP_FAILED) {
|
||||
fs->st_size <= 8 * 1024 * 1024 &&
|
||||
(p = mmap(NULL, (size_t)fs->st_size, PROT_READ,
|
||||
MAP_SHARED, from_fd, (off_t)0)) != MAP_FAILED) {
|
||||
wtotal = 0;
|
||||
for (bufp = p, wresid = fs->st_size; ;
|
||||
bufp += wcount, wresid -= (size_t)wcount) {
|
||||
wcount = write(to_fd, bufp, wresid);
|
||||
if (wcount <= 0)
|
||||
break;
|
||||
wtotal += wcount;
|
||||
if (info) {
|
||||
info = 0;
|
||||
(void)fprintf(stderr,
|
||||
"%s -> %s %3d%%\n",
|
||||
entp->fts_path, to.p_path,
|
||||
cp_pct(wtotal, fs->st_size));
|
||||
}
|
||||
if (wcount >= (ssize_t)wresid)
|
||||
break;
|
||||
}
|
||||
if (wcount != (ssize_t)wresid) {
|
||||
warn("%s", to.p_path);
|
||||
rval = 1;
|
||||
}
|
||||
/* Some systems don't unmap on close(2). */
|
||||
if (munmap(p, fs->st_size) < 0) {
|
||||
warn("%s", entp->fts_path);
|
||||
rval = 1;
|
||||
} else {
|
||||
wtotal = 0;
|
||||
for (bufp = p, wresid = fs->st_size; ;
|
||||
bufp += wcount, wresid -= (size_t)wcount) {
|
||||
wcount = write(to_fd, bufp, wresid);
|
||||
if (wcount <= 0)
|
||||
break;
|
||||
wtotal += wcount;
|
||||
if (info) {
|
||||
info = 0;
|
||||
(void)fprintf(stderr,
|
||||
"%s -> %s %3d%%\n",
|
||||
entp->fts_path, to.p_path,
|
||||
cp_pct(wtotal, fs->st_size));
|
||||
}
|
||||
if (wcount >= (ssize_t)wresid)
|
||||
break;
|
||||
}
|
||||
if (wcount != (ssize_t)wresid) {
|
||||
warn("%s", to.p_path);
|
||||
rval = 1;
|
||||
}
|
||||
/* Some systems don't unmap on close(2). */
|
||||
if (munmap(p, fs->st_size) < 0) {
|
||||
warn("%s", entp->fts_path);
|
||||
rval = 1;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (buf == NULL) {
|
||||
/*
|
||||
* Note that buf and bufsize are static. If
|
||||
* malloc() fails, it will fail at the start
|
||||
* and not copy only some files.
|
||||
*/
|
||||
if (sysconf(_SC_PHYS_PAGES) >
|
||||
PHYSPAGES_THRESHOLD)
|
||||
bufsize = MIN(BUFSIZE_MAX, MAXPHYS * 8);
|
||||
else
|
||||
bufsize = BUFSIZE_SMALL;
|
||||
buf = malloc(bufsize);
|
||||
if (buf == NULL)
|
||||
err(1, "Not enough memory");
|
||||
}
|
||||
wtotal = 0;
|
||||
while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
|
||||
while ((rcount = read(from_fd, buf, bufsize)) > 0) {
|
||||
for (bufp = buf, wresid = rcount; ;
|
||||
bufp += wcount, wresid -= wcount) {
|
||||
wcount = write(to_fd, bufp, wresid);
|
||||
|
@ -29,7 +29,7 @@
|
||||
.\" @(#)df.1 8.3 (Berkeley) 5/8/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 22, 2004
|
||||
.Dd November 23, 2008
|
||||
.Dt DF 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -38,7 +38,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl b | g | H | h | k | m | P
|
||||
.Op Fl aciln
|
||||
.Op Fl acilnT
|
||||
.Op Fl t Ar type
|
||||
.Op Ar file | filesystem ...
|
||||
.Sh DESCRIPTION
|
||||
@ -140,6 +140,8 @@ The
|
||||
.Xr lsvfs 1
|
||||
command can be used to find out the types of file systems
|
||||
that are available on the system.
|
||||
.It Fl T
|
||||
Include file system type.
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width BLOCKSIZE
|
||||
|
20
bin/df/df.c
20
bin/df/df.c
@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
|
||||
/* Maximum widths of various fields. */
|
||||
struct maxwidths {
|
||||
int mntfrom;
|
||||
int fstype;
|
||||
int total;
|
||||
int used;
|
||||
int avail;
|
||||
@ -93,7 +94,7 @@ imax(int a, int b)
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
static int aflag = 0, cflag, hflag, iflag, kflag, lflag = 0, nflag;
|
||||
static int aflag = 0, cflag, hflag, iflag, kflag, lflag = 0, nflag, Tflag;
|
||||
static struct ufs_args mdev;
|
||||
|
||||
int
|
||||
@ -115,7 +116,7 @@ main(int argc, char *argv[])
|
||||
totalbuf.f_bsize = DEV_BSIZE;
|
||||
strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN);
|
||||
vfslist = NULL;
|
||||
while ((ch = getopt(argc, argv, "abcgHhiklmnPt:")) != -1)
|
||||
while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T")) != -1)
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
aflag = 1;
|
||||
@ -176,6 +177,9 @@ main(int argc, char *argv[])
|
||||
fstype = optarg;
|
||||
vfslist = makevfslist(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
Tflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
@ -391,6 +395,7 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp)
|
||||
|
||||
if (++timesthrough == 1) {
|
||||
mwp->mntfrom = imax(mwp->mntfrom, (int)strlen("Filesystem"));
|
||||
mwp->fstype = imax(mwp->fstype, (int)strlen("Type"));
|
||||
if (hflag) {
|
||||
header = " Size";
|
||||
mwp->total = mwp->used = mwp->avail =
|
||||
@ -402,8 +407,10 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp)
|
||||
mwp->used = imax(mwp->used, (int)strlen("Used"));
|
||||
mwp->avail = imax(mwp->avail, (int)strlen("Avail"));
|
||||
|
||||
(void)printf("%-*s %-*s %*s %*s Capacity",
|
||||
mwp->mntfrom, "Filesystem", mwp->total, header,
|
||||
(void)printf("%-*s", mwp->mntfrom, "Filesystem");
|
||||
if (Tflag)
|
||||
(void)printf(" %-*s", mwp->fstype, "Type");
|
||||
(void)printf(" %-*s %*s %*s Capacity", mwp->total, header,
|
||||
mwp->used, "Used", mwp->avail, "Avail");
|
||||
if (iflag) {
|
||||
mwp->iused = imax(mwp->iused, (int)strlen(" iused"));
|
||||
@ -414,6 +421,8 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp)
|
||||
(void)printf(" Mounted on\n");
|
||||
}
|
||||
(void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname);
|
||||
if (Tflag)
|
||||
(void)printf(" %-*s", mwp->fstype, sfsp->f_fstypename);
|
||||
used = sfsp->f_blocks - sfsp->f_bfree;
|
||||
availblks = sfsp->f_bavail + used;
|
||||
if (hflag) {
|
||||
@ -468,6 +477,7 @@ update_maxwidths(struct maxwidths *mwp, const struct statfs *sfsp)
|
||||
getbsize(&dummy, &blocksize);
|
||||
|
||||
mwp->mntfrom = imax(mwp->mntfrom, (int)strlen(sfsp->f_mntfromname));
|
||||
mwp->fstype = imax(mwp->fstype, (int)strlen(sfsp->f_fstypename));
|
||||
mwp->total = imax(mwp->total, int64width(
|
||||
fsbtoblk((int64_t)sfsp->f_blocks, sfsp->f_bsize, blocksize)));
|
||||
mwp->used = imax(mwp->used,
|
||||
@ -505,7 +515,7 @@ usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr,
|
||||
"usage: df [-b | -g | -H | -h | -k | -m | -P] [-aciln] [-t type] [file | filesystem ...]\n");
|
||||
"usage: df [-b | -g | -H | -h | -k | -m | -P] [-acilnT] [-t type] [file | filesystem ...]\n");
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
|
@ -196,9 +196,8 @@ tdnam(KINFO *k, VARENT *ve)
|
||||
v = ve->var;
|
||||
if (showthreads && k->ki_p->ki_numthreads > 1)
|
||||
(void)printf("%-*s", v->width, k->ki_p->ki_ocomm);
|
||||
else
|
||||
(void)printf("%-*s", v->width, " " );
|
||||
|
||||
else
|
||||
(void)printf("%-*s", v->width, " ");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -789,6 +789,4 @@ run_err(const char *fmt, ...)
|
||||
vwarnx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
@ -791,6 +791,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
||||
for (sp = varlist.list ; sp ; sp = sp->next)
|
||||
mklocal(sp->text);
|
||||
funcnest++;
|
||||
exitstatus = oexitstatus;
|
||||
if (flags & EV_TESTED)
|
||||
evaltree(cmdentry.u.func, EV_TESTED);
|
||||
else
|
||||
|
@ -728,9 +728,6 @@ typecmd_impl(int argc, char **argv, int cmd)
|
||||
extern char *const parsekwd[];
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (cmd != TYPECMD_SMALLV)
|
||||
out1str(argv[i]);
|
||||
|
||||
/* First look at the keywords */
|
||||
for (pp = (char **)parsekwd; *pp; pp++)
|
||||
if (**pp == *argv[i] && equal(*pp, argv[i]))
|
||||
@ -740,7 +737,7 @@ typecmd_impl(int argc, char **argv, int cmd)
|
||||
if (cmd == TYPECMD_SMALLV)
|
||||
out1fmt("%s\n", argv[i]);
|
||||
else
|
||||
out1str(" is a shell keyword\n");
|
||||
out1fmt("%s is a shell keyword\n", argv[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -749,7 +746,8 @@ typecmd_impl(int argc, char **argv, int cmd)
|
||||
if (cmd == TYPECMD_SMALLV)
|
||||
out1fmt("alias %s='%s'\n", argv[i], ap->val);
|
||||
else
|
||||
out1fmt(" is an alias for %s\n", ap->val);
|
||||
out1fmt("%s is an alias for %s\n", argv[i],
|
||||
ap->val);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -775,7 +773,7 @@ typecmd_impl(int argc, char **argv, int cmd)
|
||||
if (cmd == TYPECMD_SMALLV)
|
||||
out1fmt("%s\n", name);
|
||||
else
|
||||
out1fmt(" is%s %s\n",
|
||||
out1fmt("%s is%s %s\n", argv[i],
|
||||
(cmdp && cmd == TYPECMD_TYPE) ?
|
||||
" a tracked alias for" : "",
|
||||
name);
|
||||
@ -784,11 +782,12 @@ typecmd_impl(int argc, char **argv, int cmd)
|
||||
if (cmd == TYPECMD_SMALLV)
|
||||
out1fmt("%s\n", argv[i]);
|
||||
else
|
||||
out1fmt(" is %s\n", argv[i]);
|
||||
out1fmt("%s is %s\n", argv[i],
|
||||
argv[i]);
|
||||
} else {
|
||||
if (cmd != TYPECMD_SMALLV)
|
||||
out1fmt(": %s\n",
|
||||
strerror(errno));
|
||||
outfmt(out2, "%s: %s\n",
|
||||
argv[i], strerror(errno));
|
||||
error |= 127;
|
||||
}
|
||||
}
|
||||
@ -798,19 +797,19 @@ typecmd_impl(int argc, char **argv, int cmd)
|
||||
if (cmd == TYPECMD_SMALLV)
|
||||
out1fmt("%s\n", argv[i]);
|
||||
else
|
||||
out1str(" is a shell function\n");
|
||||
out1fmt("%s is a shell function\n", argv[i]);
|
||||
break;
|
||||
|
||||
case CMDBUILTIN:
|
||||
if (cmd == TYPECMD_SMALLV)
|
||||
out1fmt("%s\n", argv[i]);
|
||||
else
|
||||
out1str(" is a shell builtin\n");
|
||||
out1fmt("%s is a shell builtin\n", argv[i]);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (cmd != TYPECMD_SMALLV)
|
||||
out1str(": not found\n");
|
||||
outfmt(out2, "%s: not found\n", argv[i]);
|
||||
error |= 127;
|
||||
break;
|
||||
}
|
||||
|
@ -4,3 +4,5 @@ OPENSOLARIS_USR_DISTDIR= ${.CURDIR}/../../../cddl/contrib/opensolaris
|
||||
OPENSOLARIS_SYS_DISTDIR= ${.CURDIR}/../../../sys/cddl/contrib/opensolaris
|
||||
|
||||
IGNORE_PRAGMA= YES
|
||||
|
||||
CFLAGS+= -DNEED_SOLARIS_BOOLEAN
|
||||
|
36
cddl/compat/opensolaris/include/libshare.h
Normal file
36
cddl/compat/opensolaris/include/libshare.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*-
|
||||
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _OPENSOLARIS_LIBSHARE_H_
|
||||
#define _OPENSOLARIS_LIBSHARE_H_
|
||||
|
||||
#define SA_OK 0
|
||||
|
||||
#define SA_INIT_CONTROL_API 0
|
||||
|
||||
#endif /* !_OPENSOLARIS_LIBSHARE_H_ */
|
@ -9,6 +9,8 @@
|
||||
#define MNTTAB _PATH_DEVNULL
|
||||
#define MNT_LINE_MAX 1024
|
||||
|
||||
#define umount2(p, f) unmount(p, f)
|
||||
|
||||
struct mnttab {
|
||||
char *mnt_special;
|
||||
char *mnt_mountp;
|
||||
|
@ -94,11 +94,7 @@ int
|
||||
devid_get(int fd, ddi_devid_t *retdevid)
|
||||
{
|
||||
|
||||
if (ioctl(fd, DIOCGIDENT, retdevid->devid) == -1)
|
||||
return (errno);
|
||||
if (retdevid->devid[0] == '\0')
|
||||
return (ENOENT);
|
||||
return (0);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mntent.h>
|
||||
#include <sys/mnttab.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static char *
|
||||
mntopt(char **p)
|
||||
|
@ -35,9 +35,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mount.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/mntent.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static void
|
||||
build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
|
||||
@ -86,7 +87,7 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype,
|
||||
assert(optlen > 0);
|
||||
|
||||
optstr = strdup(optptr);
|
||||
assert(optptr != NULL);
|
||||
assert(optstr != NULL);
|
||||
|
||||
iov = NULL;
|
||||
iovlen = 0;
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/zone.h>
|
||||
|
||||
int
|
||||
zoneid_t
|
||||
getzoneid(void)
|
||||
{
|
||||
size_t size;
|
||||
@ -42,5 +42,5 @@ getzoneid(void)
|
||||
size = sizeof(jailid);
|
||||
if (sysctlbyname("security.jail.jailed", &jailid, &size, NULL, 0) == -1)
|
||||
assert(!"No security.jail.jailed sysctl!");
|
||||
return (jailid);
|
||||
return ((zoneid_t)jailid);
|
||||
}
|
||||
|
@ -1576,7 +1576,7 @@ main(int argc, char *argv[])
|
||||
if ((v = make_argv(optarg)) == NULL)
|
||||
fatal("failed to allocate memory");
|
||||
|
||||
P = dtrace_proc_create(g_dtp, v[0], v);
|
||||
P = dtrace_proc_create(g_dtp, v[0], v, NULL, NULL);
|
||||
if (P == NULL)
|
||||
dfatal(NULL); /* dtrace_errmsg() only */
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
#ident "%Z%%M% %I% %E% SMI"
|
||||
# ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
# Exception list: names tests that are bypassed when running in Java
|
||||
# mode (relative to /opt/SUNWdtrt/tst)
|
||||
@ -49,6 +49,7 @@ common/usdt/tst.dlclose2.ksh
|
||||
common/usdt/tst.dlclose3.ksh
|
||||
common/usdt/tst.eliminate.ksh
|
||||
common/usdt/tst.enabled.ksh
|
||||
common/usdt/tst.enabled2.ksh
|
||||
common/usdt/tst.entryreturn.ksh
|
||||
common/usdt/tst.fork.ksh
|
||||
common/usdt/tst.header.ksh
|
||||
|
@ -28,13 +28,17 @@ zdb \- ZFS debugger
|
||||
.fi
|
||||
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
.LP
|
||||
The \fBzdb\fR command is used by support engineers to diagnose failures and gather statistics. Since the \fBZFS\fR file system is always consistent on disk and is self-repairing, \fBzdb\fR should only be run under the direction by a support engineer.
|
||||
.sp
|
||||
.LP
|
||||
If no arguments are specified, \fBzdb\fR, performs basic consistency checks on the pool and associated datasets, and report any problems detected.
|
||||
.sp
|
||||
.LP
|
||||
Any options supported by this command are internal to Sun and subject to change at any time.
|
||||
.SH EXIT STATUS
|
||||
.sp
|
||||
.LP
|
||||
The following exit values are returned:
|
||||
.sp
|
||||
@ -71,6 +75,7 @@ Invalid command line options were specified.
|
||||
.RE
|
||||
|
||||
.SH ATTRIBUTES
|
||||
.sp
|
||||
.LP
|
||||
See \fBattributes\fR(5) for descriptions of the following attributes:
|
||||
.sp
|
||||
@ -89,5 +94,6 @@ Interface StabilityUnstable
|
||||
.TE
|
||||
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
.LP
|
||||
\fBzfs\fR(1M), \fBzpool\fR(1M), \fBattributes\fR(5)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -233,19 +233,26 @@ typedef struct zil_rec_info {
|
||||
} zil_rec_info_t;
|
||||
|
||||
static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
|
||||
{ NULL, "Total " },
|
||||
{ zil_prt_rec_create, "TX_CREATE " },
|
||||
{ zil_prt_rec_create, "TX_MKDIR " },
|
||||
{ zil_prt_rec_create, "TX_MKXATTR " },
|
||||
{ zil_prt_rec_create, "TX_SYMLINK " },
|
||||
{ zil_prt_rec_remove, "TX_REMOVE " },
|
||||
{ zil_prt_rec_remove, "TX_RMDIR " },
|
||||
{ zil_prt_rec_link, "TX_LINK " },
|
||||
{ zil_prt_rec_rename, "TX_RENAME " },
|
||||
{ zil_prt_rec_write, "TX_WRITE " },
|
||||
{ zil_prt_rec_truncate, "TX_TRUNCATE" },
|
||||
{ zil_prt_rec_setattr, "TX_SETATTR " },
|
||||
{ zil_prt_rec_acl, "TX_ACL " },
|
||||
{ NULL, "Total " },
|
||||
{ zil_prt_rec_create, "TX_CREATE " },
|
||||
{ zil_prt_rec_create, "TX_MKDIR " },
|
||||
{ zil_prt_rec_create, "TX_MKXATTR " },
|
||||
{ zil_prt_rec_create, "TX_SYMLINK " },
|
||||
{ zil_prt_rec_remove, "TX_REMOVE " },
|
||||
{ zil_prt_rec_remove, "TX_RMDIR " },
|
||||
{ zil_prt_rec_link, "TX_LINK " },
|
||||
{ zil_prt_rec_rename, "TX_RENAME " },
|
||||
{ zil_prt_rec_write, "TX_WRITE " },
|
||||
{ zil_prt_rec_truncate, "TX_TRUNCATE " },
|
||||
{ zil_prt_rec_setattr, "TX_SETATTR " },
|
||||
{ zil_prt_rec_acl, "TX_ACL_V0 " },
|
||||
{ zil_prt_rec_acl, "TX_ACL_ACL " },
|
||||
{ zil_prt_rec_create, "TX_CREATE_ACL " },
|
||||
{ zil_prt_rec_create, "TX_CREATE_ATTR " },
|
||||
{ zil_prt_rec_create, "TX_CREATE_ACL_ATTR " },
|
||||
{ zil_prt_rec_create, "TX_MKDIR_ACL " },
|
||||
{ zil_prt_rec_create, "TX_MKDIR_ATTR " },
|
||||
{ zil_prt_rec_create, "TX_MKDIR_ACL_ATTR " },
|
||||
};
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -255,12 +262,14 @@ print_log_record(zilog_t *zilog, lr_t *lr, void *arg, uint64_t claim_txg)
|
||||
int txtype;
|
||||
int verbose = MAX(dump_opt['d'], dump_opt['i']);
|
||||
|
||||
/* reduce size of txtype to strip off TX_CI bit */
|
||||
txtype = lr->lrc_txtype;
|
||||
|
||||
ASSERT(txtype != 0 && (uint_t)txtype < TX_MAX_TYPE);
|
||||
ASSERT(lr->lrc_txg);
|
||||
|
||||
(void) printf("\t\t%s len %6llu, txg %llu, seq %llu\n",
|
||||
(void) printf("\t\t%s%s len %6llu, txg %llu, seq %llu\n",
|
||||
(lr->lrc_txtype & TX_CI) ? "CI-" : "",
|
||||
zil_rec_info[txtype].zri_name,
|
||||
(u_longlong_t)lr->lrc_reclen,
|
||||
(u_longlong_t)lr->lrc_txg,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,12 +19,10 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <libintl.h>
|
||||
#include <libuutil.h>
|
||||
#include <stddef.h>
|
||||
@ -56,28 +54,43 @@ typedef struct zfs_node {
|
||||
|
||||
typedef struct callback_data {
|
||||
uu_avl_t *cb_avl;
|
||||
int cb_recurse;
|
||||
int cb_flags;
|
||||
zfs_type_t cb_types;
|
||||
zfs_sort_column_t *cb_sortcol;
|
||||
zfs_proplist_t **cb_proplist;
|
||||
zprop_list_t **cb_proplist;
|
||||
} callback_data_t;
|
||||
|
||||
uu_avl_pool_t *avl_pool;
|
||||
|
||||
/*
|
||||
* Called for each dataset. If the object the object is of an appropriate type,
|
||||
* Include snaps if they were requested or if this a zfs list where types
|
||||
* were not specified and the "listsnapshots" property is set on this pool.
|
||||
*/
|
||||
static int
|
||||
zfs_include_snapshots(zfs_handle_t *zhp, callback_data_t *cb)
|
||||
{
|
||||
zpool_handle_t *zph;
|
||||
|
||||
if ((cb->cb_flags & ZFS_ITER_PROP_LISTSNAPS) == 0)
|
||||
return (cb->cb_types & ZFS_TYPE_SNAPSHOT);
|
||||
|
||||
zph = zfs_get_pool_handle(zhp);
|
||||
return (zpool_get_prop_int(zph, ZPOOL_PROP_LISTSNAPS, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for each dataset. If the object is of an appropriate type,
|
||||
* add it to the avl tree and recurse over any children as necessary.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
zfs_callback(zfs_handle_t *zhp, void *data)
|
||||
{
|
||||
callback_data_t *cb = data;
|
||||
int dontclose = 0;
|
||||
int include_snaps = zfs_include_snapshots(zhp, cb);
|
||||
|
||||
/*
|
||||
* If this object is of the appropriate type, add it to the AVL tree.
|
||||
*/
|
||||
if (zfs_get_type(zhp) & cb->cb_types) {
|
||||
if ((zfs_get_type(zhp) & cb->cb_types) ||
|
||||
((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
|
||||
uu_avl_index_t idx;
|
||||
zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
|
||||
|
||||
@ -100,10 +113,12 @@ zfs_callback(zfs_handle_t *zhp, void *data)
|
||||
/*
|
||||
* Recurse if necessary.
|
||||
*/
|
||||
if (cb->cb_recurse && (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM ||
|
||||
(zfs_get_type(zhp) == ZFS_TYPE_VOLUME && (cb->cb_types &
|
||||
ZFS_TYPE_SNAPSHOT))))
|
||||
(void) zfs_iter_children(zhp, zfs_callback, data);
|
||||
if (cb->cb_flags & ZFS_ITER_RECURSE) {
|
||||
if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
|
||||
(void) zfs_iter_filesystems(zhp, zfs_callback, data);
|
||||
if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps)
|
||||
(void) zfs_iter_snapshots(zhp, zfs_callback, data);
|
||||
}
|
||||
|
||||
if (!dontclose)
|
||||
zfs_close(zhp);
|
||||
@ -118,7 +133,7 @@ zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
|
||||
zfs_sort_column_t *col;
|
||||
zfs_prop_t prop;
|
||||
|
||||
if ((prop = zfs_name_to_prop(name)) == ZFS_PROP_INVAL &&
|
||||
if ((prop = zfs_name_to_prop(name)) == ZPROP_INVAL &&
|
||||
!zfs_prop_user(name))
|
||||
return (-1);
|
||||
|
||||
@ -126,7 +141,7 @@ zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
|
||||
|
||||
col->sc_prop = prop;
|
||||
col->sc_reverse = reverse;
|
||||
if (prop == ZFS_PROP_INVAL) {
|
||||
if (prop == ZPROP_INVAL) {
|
||||
col->sc_user_prop = safe_malloc(strlen(name) + 1);
|
||||
(void) strcpy(col->sc_user_prop, name);
|
||||
}
|
||||
@ -243,7 +258,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
|
||||
* Otherwise, we compare 'lnum' and 'rnum'.
|
||||
*/
|
||||
lstr = rstr = NULL;
|
||||
if (psc->sc_prop == ZFS_PROP_INVAL) {
|
||||
if (psc->sc_prop == ZPROP_INVAL) {
|
||||
nvlist_t *luser, *ruser;
|
||||
nvlist_t *lval, *rval;
|
||||
|
||||
@ -257,10 +272,10 @@ zfs_sort(const void *larg, const void *rarg, void *data)
|
||||
|
||||
if (lvalid)
|
||||
verify(nvlist_lookup_string(lval,
|
||||
ZFS_PROP_VALUE, &lstr) == 0);
|
||||
ZPROP_VALUE, &lstr) == 0);
|
||||
if (rvalid)
|
||||
verify(nvlist_lookup_string(rval,
|
||||
ZFS_PROP_VALUE, &rstr) == 0);
|
||||
ZPROP_VALUE, &rstr) == 0);
|
||||
|
||||
} else if (zfs_prop_is_string(psc->sc_prop)) {
|
||||
lvalid = (zfs_prop_get(l, psc->sc_prop, lbuf,
|
||||
@ -293,7 +308,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
|
||||
|
||||
if (lstr)
|
||||
ret = strcmp(lstr, rstr);
|
||||
if (lnum < rnum)
|
||||
else if (lnum < rnum)
|
||||
ret = -1;
|
||||
else if (lnum > rnum)
|
||||
ret = 1;
|
||||
@ -309,9 +324,9 @@ zfs_sort(const void *larg, const void *rarg, void *data)
|
||||
}
|
||||
|
||||
int
|
||||
zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
|
||||
zfs_sort_column_t *sortcol, zfs_proplist_t **proplist, zfs_iter_f callback,
|
||||
void *data, boolean_t args_can_be_paths)
|
||||
zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
|
||||
zfs_sort_column_t *sortcol, zprop_list_t **proplist,
|
||||
zfs_iter_f callback, void *data)
|
||||
{
|
||||
callback_data_t cb;
|
||||
int ret = 0;
|
||||
@ -328,7 +343,7 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
|
||||
}
|
||||
|
||||
cb.cb_sortcol = sortcol;
|
||||
cb.cb_recurse = recurse;
|
||||
cb.cb_flags = flags;
|
||||
cb.cb_proplist = proplist;
|
||||
cb.cb_types = types;
|
||||
if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) {
|
||||
@ -341,7 +356,7 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
|
||||
/*
|
||||
* If given no arguments, iterate over all datasets.
|
||||
*/
|
||||
cb.cb_recurse = 1;
|
||||
cb.cb_flags |= ZFS_ITER_RECURSE;
|
||||
ret = zfs_iter_root(g_zfs, zfs_callback, &cb);
|
||||
} else {
|
||||
int i;
|
||||
@ -354,14 +369,14 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
|
||||
* can take volumes as well.
|
||||
*/
|
||||
argtype = types;
|
||||
if (recurse) {
|
||||
if (flags & ZFS_ITER_RECURSE) {
|
||||
argtype |= ZFS_TYPE_FILESYSTEM;
|
||||
if (types & ZFS_TYPE_SNAPSHOT)
|
||||
argtype |= ZFS_TYPE_VOLUME;
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (args_can_be_paths) {
|
||||
if (flags & ZFS_ITER_ARGS_CAN_BE_PATHS) {
|
||||
zhp = zfs_path_to_zhandle(g_zfs, argv[i],
|
||||
argtype);
|
||||
} else {
|
||||
|
@ -19,15 +19,13 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef ZFS_ITER_H
|
||||
#define ZFS_ITER_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -40,8 +38,12 @@ typedef struct zfs_sort_column {
|
||||
boolean_t sc_reverse;
|
||||
} zfs_sort_column_t;
|
||||
|
||||
int zfs_for_each(int, char **, boolean_t, zfs_type_t, zfs_sort_column_t *,
|
||||
zfs_proplist_t **, zfs_iter_f, void *, boolean_t);
|
||||
#define ZFS_ITER_RECURSE (1 << 0)
|
||||
#define ZFS_ITER_ARGS_CAN_BE_PATHS (1 << 1)
|
||||
#define ZFS_ITER_PROP_LISTSNAPS (1 << 2)
|
||||
|
||||
int zfs_for_each(int, char **, int options, zfs_type_t,
|
||||
zfs_sort_column_t *, zprop_list_t **, zfs_iter_f, void *);
|
||||
int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t);
|
||||
void zfs_free_sort_columns(zfs_sort_column_t *);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
460
cddl/contrib/opensolaris/cmd/zinject/translate.c
Normal file
460
cddl/contrib/opensolaris/cmd/zinject/translate.c
Normal file
@ -0,0 +1,460 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* 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]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <libzfs.h>
|
||||
|
||||
#undef verify /* both libzfs.h and zfs_context.h want to define this */
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/mntent.h>
|
||||
#include <sys/mnttab.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <sys/dmu.h>
|
||||
#include <sys/dmu_objset.h>
|
||||
#include <sys/dnode.h>
|
||||
#include <sys/vdev_impl.h>
|
||||
|
||||
#include "zinject.h"
|
||||
|
||||
#include <assert.h>
|
||||
#define verify assert
|
||||
|
||||
extern void kernel_init(int);
|
||||
extern void kernel_fini(void);
|
||||
|
||||
static int debug;
|
||||
|
||||
static void
|
||||
ziprintf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (!debug)
|
||||
return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(void) vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a full path to a file, translate into a dataset name and a relative
|
||||
* path within the dataset. 'dataset' must be at least MAXNAMELEN characters,
|
||||
* and 'relpath' must be at least MAXPATHLEN characters. We also pass a stat64
|
||||
* buffer, which we need later to get the object ID.
|
||||
*/
|
||||
static int
|
||||
parse_pathname(const char *fullpath, char *dataset, char *relpath,
|
||||
struct stat64 *statbuf)
|
||||
{
|
||||
struct statfs sfs;
|
||||
const char *rel;
|
||||
|
||||
if (fullpath[0] != '/') {
|
||||
(void) fprintf(stderr, "invalid object '%s': must be full "
|
||||
"path\n", fullpath);
|
||||
usage();
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (strlen(fullpath) >= MAXPATHLEN) {
|
||||
(void) fprintf(stderr, "invalid object; pathname too long\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (stat64(fullpath, statbuf) != 0) {
|
||||
(void) fprintf(stderr, "cannot open '%s': %s\n",
|
||||
fullpath, strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (statfs(fullpath, &sfs) == -1) {
|
||||
(void) fprintf(stderr, "cannot find mountpoint for '%s': %s\n",
|
||||
fullpath, strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (strcmp(sfs.f_fstypename, MNTTYPE_ZFS) != 0) {
|
||||
(void) fprintf(stderr, "invalid path '%s': not a ZFS "
|
||||
"filesystem\n", fullpath);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (strncmp(fullpath, sfs.f_mntonname, strlen(sfs.f_mntonname)) != 0) {
|
||||
(void) fprintf(stderr, "invalid path '%s': mountpoint "
|
||||
"doesn't match path\n", fullpath);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
(void) strcpy(dataset, sfs.f_mntfromname);
|
||||
|
||||
rel = fullpath + strlen(sfs.f_mntonname);
|
||||
if (rel[0] == '/')
|
||||
rel++;
|
||||
(void) strcpy(relpath, rel);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert from a (dataset, path) pair into a (objset, object) pair. Note that
|
||||
* we grab the object number from the inode number, since looking this up via
|
||||
* libzpool is a real pain.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
object_from_path(const char *dataset, const char *path, struct stat64 *statbuf,
|
||||
zinject_record_t *record)
|
||||
{
|
||||
objset_t *os;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Before doing any libzpool operations, call sync() to ensure that the
|
||||
* on-disk state is consistent with the in-core state.
|
||||
*/
|
||||
sync();
|
||||
|
||||
if ((err = dmu_objset_open(dataset, DMU_OST_ZFS,
|
||||
DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) {
|
||||
(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
|
||||
dataset, strerror(err));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
record->zi_objset = dmu_objset_id(os);
|
||||
record->zi_object = statbuf->st_ino;
|
||||
|
||||
dmu_objset_close(os);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the real range based on the type, level, and range given.
|
||||
*/
|
||||
static int
|
||||
calculate_range(const char *dataset, err_type_t type, int level, char *range,
|
||||
zinject_record_t *record)
|
||||
{
|
||||
objset_t *os = NULL;
|
||||
dnode_t *dn = NULL;
|
||||
int err;
|
||||
int ret = -1;
|
||||
|
||||
/*
|
||||
* Determine the numeric range from the string.
|
||||
*/
|
||||
if (range == NULL) {
|
||||
/*
|
||||
* If range is unspecified, set the range to [0,-1], which
|
||||
* indicates that the whole object should be treated as an
|
||||
* error.
|
||||
*/
|
||||
record->zi_start = 0;
|
||||
record->zi_end = -1ULL;
|
||||
} else {
|
||||
char *end;
|
||||
|
||||
/* XXX add support for suffixes */
|
||||
record->zi_start = strtoull(range, &end, 10);
|
||||
|
||||
|
||||
if (*end == '\0')
|
||||
record->zi_end = record->zi_start + 1;
|
||||
else if (*end == ',')
|
||||
record->zi_end = strtoull(end + 1, &end, 10);
|
||||
|
||||
if (*end != '\0') {
|
||||
(void) fprintf(stderr, "invalid range '%s': must be "
|
||||
"a numeric range of the form 'start[,end]'\n",
|
||||
range);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case TYPE_DATA:
|
||||
break;
|
||||
|
||||
case TYPE_DNODE:
|
||||
/*
|
||||
* If this is a request to inject faults into the dnode, then we
|
||||
* must translate the current (objset,object) pair into an
|
||||
* offset within the metadnode for the objset. Specifying any
|
||||
* kind of range with type 'dnode' is illegal.
|
||||
*/
|
||||
if (range != NULL) {
|
||||
(void) fprintf(stderr, "range cannot be specified when "
|
||||
"type is 'dnode'\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
record->zi_start = record->zi_object * sizeof (dnode_phys_t);
|
||||
record->zi_end = record->zi_start + sizeof (dnode_phys_t);
|
||||
record->zi_object = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the dnode associated with object, so we can calculate the block
|
||||
* size.
|
||||
*/
|
||||
if ((err = dmu_objset_open(dataset, DMU_OST_ANY,
|
||||
DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) {
|
||||
(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
|
||||
dataset, strerror(err));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (record->zi_object == 0) {
|
||||
dn = os->os->os_meta_dnode;
|
||||
} else {
|
||||
err = dnode_hold(os->os, record->zi_object, FTAG, &dn);
|
||||
if (err != 0) {
|
||||
(void) fprintf(stderr, "failed to hold dnode "
|
||||
"for object %llu\n",
|
||||
(u_longlong_t)record->zi_object);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ziprintf("data shift: %d\n", (int)dn->dn_datablkshift);
|
||||
ziprintf(" ind shift: %d\n", (int)dn->dn_indblkshift);
|
||||
|
||||
/*
|
||||
* Translate range into block IDs.
|
||||
*/
|
||||
if (record->zi_start != 0 || record->zi_end != -1ULL) {
|
||||
record->zi_start >>= dn->dn_datablkshift;
|
||||
record->zi_end >>= dn->dn_datablkshift;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check level, and then translate level 0 blkids into ranges
|
||||
* appropriate for level of indirection.
|
||||
*/
|
||||
record->zi_level = level;
|
||||
if (level > 0) {
|
||||
ziprintf("level 0 blkid range: [%llu, %llu]\n",
|
||||
record->zi_start, record->zi_end);
|
||||
|
||||
if (level >= dn->dn_nlevels) {
|
||||
(void) fprintf(stderr, "level %d exceeds max level "
|
||||
"of object (%d)\n", level, dn->dn_nlevels - 1);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (record->zi_start != 0 || record->zi_end != 0) {
|
||||
int shift = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
|
||||
|
||||
for (; level > 0; level--) {
|
||||
record->zi_start >>= shift;
|
||||
record->zi_end >>= shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (dn) {
|
||||
if (dn != os->os->os_meta_dnode)
|
||||
dnode_rele(dn, FTAG);
|
||||
}
|
||||
if (os)
|
||||
dmu_objset_close(os);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
translate_record(err_type_t type, const char *object, const char *range,
|
||||
int level, zinject_record_t *record, char *poolname, char *dataset)
|
||||
{
|
||||
char path[MAXPATHLEN];
|
||||
char *slash;
|
||||
struct stat64 statbuf;
|
||||
int ret = -1;
|
||||
|
||||
kernel_init(FREAD);
|
||||
|
||||
debug = (getenv("ZINJECT_DEBUG") != NULL);
|
||||
|
||||
ziprintf("translating: %s\n", object);
|
||||
|
||||
if (MOS_TYPE(type)) {
|
||||
/*
|
||||
* MOS objects are treated specially.
|
||||
*/
|
||||
switch (type) {
|
||||
case TYPE_MOS:
|
||||
record->zi_type = 0;
|
||||
break;
|
||||
case TYPE_MOSDIR:
|
||||
record->zi_type = DMU_OT_OBJECT_DIRECTORY;
|
||||
break;
|
||||
case TYPE_METASLAB:
|
||||
record->zi_type = DMU_OT_OBJECT_ARRAY;
|
||||
break;
|
||||
case TYPE_CONFIG:
|
||||
record->zi_type = DMU_OT_PACKED_NVLIST;
|
||||
break;
|
||||
case TYPE_BPLIST:
|
||||
record->zi_type = DMU_OT_BPLIST;
|
||||
break;
|
||||
case TYPE_SPACEMAP:
|
||||
record->zi_type = DMU_OT_SPACE_MAP;
|
||||
break;
|
||||
case TYPE_ERRLOG:
|
||||
record->zi_type = DMU_OT_ERROR_LOG;
|
||||
break;
|
||||
}
|
||||
|
||||
dataset[0] = '\0';
|
||||
(void) strcpy(poolname, object);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a full path into a (dataset, file) pair.
|
||||
*/
|
||||
if (parse_pathname(object, dataset, path, &statbuf) != 0)
|
||||
goto err;
|
||||
|
||||
ziprintf(" dataset: %s\n", dataset);
|
||||
ziprintf(" path: %s\n", path);
|
||||
|
||||
/*
|
||||
* Convert (dataset, file) into (objset, object)
|
||||
*/
|
||||
if (object_from_path(dataset, path, &statbuf, record) != 0)
|
||||
goto err;
|
||||
|
||||
ziprintf("raw objset: %llu\n", record->zi_objset);
|
||||
ziprintf("raw object: %llu\n", record->zi_object);
|
||||
|
||||
/*
|
||||
* For the given object, calculate the real (type, level, range)
|
||||
*/
|
||||
if (calculate_range(dataset, type, level, (char *)range, record) != 0)
|
||||
goto err;
|
||||
|
||||
ziprintf(" objset: %llu\n", record->zi_objset);
|
||||
ziprintf(" object: %llu\n", record->zi_object);
|
||||
if (record->zi_start == 0 &&
|
||||
record->zi_end == -1ULL)
|
||||
ziprintf(" range: all\n");
|
||||
else
|
||||
ziprintf(" range: [%llu, %llu]\n", record->zi_start,
|
||||
record->zi_end);
|
||||
|
||||
/*
|
||||
* Copy the pool name
|
||||
*/
|
||||
(void) strcpy(poolname, dataset);
|
||||
if ((slash = strchr(poolname, '/')) != NULL)
|
||||
*slash = '\0';
|
||||
|
||||
ret = 0;
|
||||
|
||||
err:
|
||||
kernel_fini();
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
translate_raw(const char *str, zinject_record_t *record)
|
||||
{
|
||||
/*
|
||||
* A raw bookmark of the form objset:object:level:blkid, where each
|
||||
* number is a hexidecimal value.
|
||||
*/
|
||||
if (sscanf(str, "%llx:%llx:%x:%llx", (u_longlong_t *)&record->zi_objset,
|
||||
(u_longlong_t *)&record->zi_object, &record->zi_level,
|
||||
(u_longlong_t *)&record->zi_start) != 4) {
|
||||
(void) fprintf(stderr, "bad raw spec '%s': must be of the form "
|
||||
"'objset:object:level:blkid'\n", str);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
record->zi_end = record->zi_start;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
translate_device(const char *pool, const char *device, err_type_t label_type,
|
||||
zinject_record_t *record)
|
||||
{
|
||||
char *end;
|
||||
zpool_handle_t *zhp;
|
||||
nvlist_t *tgt;
|
||||
boolean_t isspare, iscache;
|
||||
|
||||
/*
|
||||
* Given a device name or GUID, create an appropriate injection record
|
||||
* with zi_guid set.
|
||||
*/
|
||||
if ((zhp = zpool_open(g_zfs, pool)) == NULL)
|
||||
return (-1);
|
||||
|
||||
record->zi_guid = strtoull(device, &end, 16);
|
||||
if (record->zi_guid == 0 || *end != '\0') {
|
||||
tgt = zpool_find_vdev(zhp, device, &isspare, &iscache, NULL);
|
||||
|
||||
if (tgt == NULL) {
|
||||
(void) fprintf(stderr, "cannot find device '%s' in "
|
||||
"pool '%s'\n", device, pool);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
|
||||
&record->zi_guid) == 0);
|
||||
}
|
||||
|
||||
switch (label_type) {
|
||||
case TYPE_LABEL_UBERBLOCK:
|
||||
record->zi_start = offsetof(vdev_label_t, vl_uberblock[0]);
|
||||
record->zi_end = record->zi_start + VDEV_UBERBLOCK_RING - 1;
|
||||
break;
|
||||
case TYPE_LABEL_NVLIST:
|
||||
record->zi_start = offsetof(vdev_label_t, vl_vdev_phys);
|
||||
record->zi_end = record->zi_start + VDEV_PHYS_SIZE - 1;
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
770
cddl/contrib/opensolaris/cmd/zinject/zinject.c
Normal file
770
cddl/contrib/opensolaris/cmd/zinject/zinject.c
Normal file
@ -0,0 +1,770 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* 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]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
/*
|
||||
* ZFS Fault Injector
|
||||
*
|
||||
* This userland component takes a set of options and uses libzpool to translate
|
||||
* from a user-visible object type and name to an internal representation.
|
||||
* There are two basic types of faults: device faults and data faults.
|
||||
*
|
||||
*
|
||||
* DEVICE FAULTS
|
||||
*
|
||||
* Errors can be injected into a particular vdev using the '-d' option. This
|
||||
* option takes a path or vdev GUID to uniquely identify the device within a
|
||||
* pool. There are two types of errors that can be injected, EIO and ENXIO,
|
||||
* that can be controlled through the '-e' option. The default is ENXIO. For
|
||||
* EIO failures, any attempt to read data from the device will return EIO, but
|
||||
* subsequent attempt to reopen the device will succeed. For ENXIO failures,
|
||||
* any attempt to read from the device will return EIO, but any attempt to
|
||||
* reopen the device will also return ENXIO.
|
||||
* For label faults, the -L option must be specified. This allows faults
|
||||
* to be injected into either the nvlist or uberblock region of all the labels
|
||||
* for the specified device.
|
||||
*
|
||||
* This form of the command looks like:
|
||||
*
|
||||
* zinject -d device [-e errno] [-L <uber | nvlist>] pool
|
||||
*
|
||||
*
|
||||
* DATA FAULTS
|
||||
*
|
||||
* We begin with a tuple of the form:
|
||||
*
|
||||
* <type,level,range,object>
|
||||
*
|
||||
* type A string describing the type of data to target. Each type
|
||||
* implicitly describes how to interpret 'object'. Currently,
|
||||
* the following values are supported:
|
||||
*
|
||||
* data User data for a file
|
||||
* dnode Dnode for a file or directory
|
||||
*
|
||||
* The following MOS objects are special. Instead of injecting
|
||||
* errors on a particular object or blkid, we inject errors across
|
||||
* all objects of the given type.
|
||||
*
|
||||
* mos Any data in the MOS
|
||||
* mosdir object directory
|
||||
* config pool configuration
|
||||
* bplist blkptr list
|
||||
* spacemap spacemap
|
||||
* metaslab metaslab
|
||||
* errlog persistent error log
|
||||
*
|
||||
* level Object level. Defaults to '0', not applicable to all types. If
|
||||
* a range is given, this corresponds to the indirect block
|
||||
* corresponding to the specific range.
|
||||
*
|
||||
* range A numerical range [start,end) within the object. Defaults to
|
||||
* the full size of the file.
|
||||
*
|
||||
* object A string describing the logical location of the object. For
|
||||
* files and directories (currently the only supported types),
|
||||
* this is the path of the object on disk.
|
||||
*
|
||||
* This is translated, via libzpool, into the following internal representation:
|
||||
*
|
||||
* <type,objset,object,level,range>
|
||||
*
|
||||
* These types should be self-explanatory. This tuple is then passed to the
|
||||
* kernel via a special ioctl() to initiate fault injection for the given
|
||||
* object. Note that 'type' is not strictly necessary for fault injection, but
|
||||
* is used when translating existing faults into a human-readable string.
|
||||
*
|
||||
*
|
||||
* The command itself takes one of the forms:
|
||||
*
|
||||
* zinject
|
||||
* zinject <-a | -u pool>
|
||||
* zinject -c <id|all>
|
||||
* zinject [-q] <-t type> [-f freq] [-u] [-a] [-m] [-e errno] [-l level]
|
||||
* [-r range] <object>
|
||||
* zinject [-f freq] [-a] [-m] [-u] -b objset:object:level:start:end pool
|
||||
*
|
||||
* With no arguments, the command prints all currently registered injection
|
||||
* handlers, with their numeric identifiers.
|
||||
*
|
||||
* The '-c' option will clear the given handler, or all handlers if 'all' is
|
||||
* specified.
|
||||
*
|
||||
* The '-e' option takes a string describing the errno to simulate. This must
|
||||
* be either 'io' or 'checksum'. In most cases this will result in the same
|
||||
* behavior, but RAID-Z will produce a different set of ereports for this
|
||||
* situation.
|
||||
*
|
||||
* The '-a', '-u', and '-m' flags toggle internal flush behavior. If '-a' is
|
||||
* specified, then the ARC cache is flushed appropriately. If '-u' is
|
||||
* specified, then the underlying SPA is unloaded. Either of these flags can be
|
||||
* specified independently of any other handlers. The '-m' flag automatically
|
||||
* does an unmount and remount of the underlying dataset to aid in flushing the
|
||||
* cache.
|
||||
*
|
||||
* The '-f' flag controls the frequency of errors injected, expressed as a
|
||||
* integer percentage between 1 and 100. The default is 100.
|
||||
*
|
||||
* The this form is responsible for actually injecting the handler into the
|
||||
* framework. It takes the arguments described above, translates them to the
|
||||
* internal tuple using libzpool, and then issues an ioctl() to register the
|
||||
* handler.
|
||||
*
|
||||
* The final form can target a specific bookmark, regardless of whether a
|
||||
* human-readable interface has been designed. It allows developers to specify
|
||||
* a particular block by number.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/fs/zfs.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <libzfs.h>
|
||||
|
||||
#undef verify /* both libzfs.h and zfs_context.h want to define this */
|
||||
|
||||
#include "zinject.h"
|
||||
|
||||
libzfs_handle_t *g_zfs;
|
||||
int zfs_fd;
|
||||
|
||||
#ifndef ECKSUM
|
||||
#define ECKSUM EBADE
|
||||
#endif
|
||||
|
||||
static const char *errtable[TYPE_INVAL] = {
|
||||
"data",
|
||||
"dnode",
|
||||
"mos",
|
||||
"mosdir",
|
||||
"metaslab",
|
||||
"config",
|
||||
"bplist",
|
||||
"spacemap",
|
||||
"errlog",
|
||||
"uber",
|
||||
"nvlist"
|
||||
};
|
||||
|
||||
static err_type_t
|
||||
name_to_type(const char *arg)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < TYPE_INVAL; i++)
|
||||
if (strcmp(errtable[i], arg) == 0)
|
||||
return (i);
|
||||
|
||||
return (TYPE_INVAL);
|
||||
}
|
||||
|
||||
static const char *
|
||||
type_to_name(uint64_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case DMU_OT_OBJECT_DIRECTORY:
|
||||
return ("mosdir");
|
||||
case DMU_OT_OBJECT_ARRAY:
|
||||
return ("metaslab");
|
||||
case DMU_OT_PACKED_NVLIST:
|
||||
return ("config");
|
||||
case DMU_OT_BPLIST:
|
||||
return ("bplist");
|
||||
case DMU_OT_SPACE_MAP:
|
||||
return ("spacemap");
|
||||
case DMU_OT_ERROR_LOG:
|
||||
return ("errlog");
|
||||
default:
|
||||
return ("-");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print usage message.
|
||||
*/
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
(void) printf(
|
||||
"usage:\n"
|
||||
"\n"
|
||||
"\tzinject\n"
|
||||
"\n"
|
||||
"\t\tList all active injection records.\n"
|
||||
"\n"
|
||||
"\tzinject -c <id|all>\n"
|
||||
"\n"
|
||||
"\t\tClear the particular record (if given a numeric ID), or\n"
|
||||
"\t\tall records if 'all' is specificed.\n"
|
||||
"\n"
|
||||
"\tzinject -d device [-e errno] [-L <nvlist|uber>] pool\n"
|
||||
"\t\tInject a fault into a particular device or the device's\n"
|
||||
"\t\tlabel. Label injection can either be 'nvlist' or 'uber'.\n"
|
||||
"\t\t'errno' can either be 'nxio' (the default) or 'io'.\n"
|
||||
"\n"
|
||||
"\tzinject -b objset:object:level:blkid pool\n"
|
||||
"\n"
|
||||
"\t\tInject an error into pool 'pool' with the numeric bookmark\n"
|
||||
"\t\tspecified by the remaining tuple. Each number is in\n"
|
||||
"\t\thexidecimal, and only one block can be specified.\n"
|
||||
"\n"
|
||||
"\tzinject [-q] <-t type> [-e errno] [-l level] [-r range]\n"
|
||||
"\t [-a] [-m] [-u] [-f freq] <object>\n"
|
||||
"\n"
|
||||
"\t\tInject an error into the object specified by the '-t' option\n"
|
||||
"\t\tand the object descriptor. The 'object' parameter is\n"
|
||||
"\t\tinterperted depending on the '-t' option.\n"
|
||||
"\n"
|
||||
"\t\t-q\tQuiet mode. Only print out the handler number added.\n"
|
||||
"\t\t-e\tInject a specific error. Must be either 'io' or\n"
|
||||
"\t\t\t'checksum'. Default is 'io'.\n"
|
||||
"\t\t-l\tInject error at a particular block level. Default is "
|
||||
"0.\n"
|
||||
"\t\t-m\tAutomatically remount underlying filesystem.\n"
|
||||
"\t\t-r\tInject error over a particular logical range of an\n"
|
||||
"\t\t\tobject. Will be translated to the appropriate blkid\n"
|
||||
"\t\t\trange according to the object's properties.\n"
|
||||
"\t\t-a\tFlush the ARC cache. Can be specified without any\n"
|
||||
"\t\t\tassociated object.\n"
|
||||
"\t\t-u\tUnload the associated pool. Can be specified with only\n"
|
||||
"\t\t\ta pool object.\n"
|
||||
"\t\t-f\tOnly inject errors a fraction of the time. Expressed as\n"
|
||||
"\t\t\ta percentage between 1 and 100.\n"
|
||||
"\n"
|
||||
"\t-t data\t\tInject an error into the plain file contents of a\n"
|
||||
"\t\t\tfile. The object must be specified as a complete path\n"
|
||||
"\t\t\tto a file on a ZFS filesystem.\n"
|
||||
"\n"
|
||||
"\t-t dnode\tInject an error into the metadnode in the block\n"
|
||||
"\t\t\tcorresponding to the dnode for a file or directory. The\n"
|
||||
"\t\t\t'-r' option is incompatible with this mode. The object\n"
|
||||
"\t\t\tis specified as a complete path to a file or directory\n"
|
||||
"\t\t\ton a ZFS filesystem.\n"
|
||||
"\n"
|
||||
"\t-t <mos>\tInject errors into the MOS for objects of the given\n"
|
||||
"\t\t\ttype. Valid types are: mos, mosdir, config, bplist,\n"
|
||||
"\t\t\tspacemap, metaslab, errlog. The only valid <object> is\n"
|
||||
"\t\t\tthe poolname.\n");
|
||||
}
|
||||
|
||||
static int
|
||||
iter_handlers(int (*func)(int, const char *, zinject_record_t *, void *),
|
||||
void *data)
|
||||
{
|
||||
zfs_cmd_t zc;
|
||||
int ret;
|
||||
|
||||
zc.zc_guid = 0;
|
||||
|
||||
while (ioctl(zfs_fd, ZFS_IOC_INJECT_LIST_NEXT, &zc) == 0)
|
||||
if ((ret = func((int)zc.zc_guid, zc.zc_name,
|
||||
&zc.zc_inject_record, data)) != 0)
|
||||
return (ret);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
print_data_handler(int id, const char *pool, zinject_record_t *record,
|
||||
void *data)
|
||||
{
|
||||
int *count = data;
|
||||
|
||||
if (record->zi_guid != 0)
|
||||
return (0);
|
||||
|
||||
if (*count == 0) {
|
||||
(void) printf("%3s %-15s %-6s %-6s %-8s %3s %-15s\n",
|
||||
"ID", "POOL", "OBJSET", "OBJECT", "TYPE", "LVL", "RANGE");
|
||||
(void) printf("--- --------------- ------ "
|
||||
"------ -------- --- ---------------\n");
|
||||
}
|
||||
|
||||
*count += 1;
|
||||
|
||||
(void) printf("%3d %-15s %-6llu %-6llu %-8s %3d ", id, pool,
|
||||
(u_longlong_t)record->zi_objset, (u_longlong_t)record->zi_object,
|
||||
type_to_name(record->zi_type), record->zi_level);
|
||||
|
||||
if (record->zi_start == 0 &&
|
||||
record->zi_end == -1ULL)
|
||||
(void) printf("all\n");
|
||||
else
|
||||
(void) printf("[%llu, %llu]\n", (u_longlong_t)record->zi_start,
|
||||
(u_longlong_t)record->zi_end);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
print_device_handler(int id, const char *pool, zinject_record_t *record,
|
||||
void *data)
|
||||
{
|
||||
int *count = data;
|
||||
|
||||
if (record->zi_guid == 0)
|
||||
return (0);
|
||||
|
||||
if (*count == 0) {
|
||||
(void) printf("%3s %-15s %s\n", "ID", "POOL", "GUID");
|
||||
(void) printf("--- --------------- ----------------\n");
|
||||
}
|
||||
|
||||
*count += 1;
|
||||
|
||||
(void) printf("%3d %-15s %llx\n", id, pool,
|
||||
(u_longlong_t)record->zi_guid);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print all registered error handlers. Returns the number of handlers
|
||||
* registered.
|
||||
*/
|
||||
static int
|
||||
print_all_handlers(void)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
(void) iter_handlers(print_device_handler, &count);
|
||||
(void) printf("\n");
|
||||
count = 0;
|
||||
(void) iter_handlers(print_data_handler, &count);
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
cancel_one_handler(int id, const char *pool, zinject_record_t *record,
|
||||
void *data)
|
||||
{
|
||||
zfs_cmd_t zc;
|
||||
|
||||
zc.zc_guid = (uint64_t)id;
|
||||
|
||||
if (ioctl(zfs_fd, ZFS_IOC_CLEAR_FAULT, &zc) != 0) {
|
||||
(void) fprintf(stderr, "failed to remove handler %d: %s\n",
|
||||
id, strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove all fault injection handlers.
|
||||
*/
|
||||
static int
|
||||
cancel_all_handlers(void)
|
||||
{
|
||||
int ret = iter_handlers(cancel_one_handler, NULL);
|
||||
|
||||
(void) printf("removed all registered handlers\n");
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a specific fault injection handler.
|
||||
*/
|
||||
static int
|
||||
cancel_handler(int id)
|
||||
{
|
||||
zfs_cmd_t zc;
|
||||
|
||||
zc.zc_guid = (uint64_t)id;
|
||||
|
||||
if (ioctl(zfs_fd, ZFS_IOC_CLEAR_FAULT, &zc) != 0) {
|
||||
(void) fprintf(stderr, "failed to remove handler %d: %s\n",
|
||||
id, strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
(void) printf("removed handler %d\n", id);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a new fault injection handler.
|
||||
*/
|
||||
static int
|
||||
register_handler(const char *pool, int flags, zinject_record_t *record,
|
||||
int quiet)
|
||||
{
|
||||
zfs_cmd_t zc;
|
||||
|
||||
(void) strcpy(zc.zc_name, pool);
|
||||
zc.zc_inject_record = *record;
|
||||
zc.zc_guid = flags;
|
||||
|
||||
if (ioctl(zfs_fd, ZFS_IOC_INJECT_FAULT, &zc) != 0) {
|
||||
(void) fprintf(stderr, "failed to add handler: %s\n",
|
||||
strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (flags & ZINJECT_NULL)
|
||||
return (0);
|
||||
|
||||
if (quiet) {
|
||||
(void) printf("%llu\n", (u_longlong_t)zc.zc_guid);
|
||||
} else {
|
||||
(void) printf("Added handler %llu with the following "
|
||||
"properties:\n", (u_longlong_t)zc.zc_guid);
|
||||
(void) printf(" pool: %s\n", pool);
|
||||
if (record->zi_guid) {
|
||||
(void) printf(" vdev: %llx\n",
|
||||
(u_longlong_t)record->zi_guid);
|
||||
} else {
|
||||
(void) printf("objset: %llu\n",
|
||||
(u_longlong_t)record->zi_objset);
|
||||
(void) printf("object: %llu\n",
|
||||
(u_longlong_t)record->zi_object);
|
||||
(void) printf(" type: %llu\n",
|
||||
(u_longlong_t)record->zi_type);
|
||||
(void) printf(" level: %d\n", record->zi_level);
|
||||
if (record->zi_start == 0 &&
|
||||
record->zi_end == -1ULL)
|
||||
(void) printf(" range: all\n");
|
||||
else
|
||||
(void) printf(" range: [%llu, %llu)\n",
|
||||
(u_longlong_t)record->zi_start,
|
||||
(u_longlong_t)record->zi_end);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
char *range = NULL;
|
||||
char *cancel = NULL;
|
||||
char *end;
|
||||
char *raw = NULL;
|
||||
char *device = NULL;
|
||||
int level = 0;
|
||||
int quiet = 0;
|
||||
int error = 0;
|
||||
int domount = 0;
|
||||
err_type_t type = TYPE_INVAL;
|
||||
err_type_t label = TYPE_INVAL;
|
||||
zinject_record_t record = { 0 };
|
||||
char pool[MAXNAMELEN];
|
||||
char dataset[MAXNAMELEN];
|
||||
zfs_handle_t *zhp;
|
||||
int ret;
|
||||
int flags = 0;
|
||||
|
||||
if ((g_zfs = libzfs_init()) == NULL) {
|
||||
(void) fprintf(stderr, "internal error: failed to "
|
||||
"initialize ZFS library\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
libzfs_print_on_error(g_zfs, B_TRUE);
|
||||
|
||||
if ((zfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
|
||||
(void) fprintf(stderr, "failed to open ZFS device\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (argc == 1) {
|
||||
/*
|
||||
* No arguments. Print the available handlers. If there are no
|
||||
* available handlers, direct the user to '-h' for help
|
||||
* information.
|
||||
*/
|
||||
if (print_all_handlers() == 0) {
|
||||
(void) printf("No handlers registered.\n");
|
||||
(void) printf("Run 'zinject -h' for usage "
|
||||
"information.\n");
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
while ((c = getopt(argc, argv, ":ab:d:f:qhc:t:l:mr:e:uL:")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
flags |= ZINJECT_FLUSH_ARC;
|
||||
break;
|
||||
case 'b':
|
||||
raw = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
cancel = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'e':
|
||||
if (strcasecmp(optarg, "io") == 0) {
|
||||
error = EIO;
|
||||
} else if (strcasecmp(optarg, "checksum") == 0) {
|
||||
error = ECKSUM;
|
||||
} else if (strcasecmp(optarg, "nxio") == 0) {
|
||||
error = ENXIO;
|
||||
} else {
|
||||
(void) fprintf(stderr, "invalid error type "
|
||||
"'%s': must be 'io', 'checksum' or "
|
||||
"'nxio'\n", optarg);
|
||||
usage();
|
||||
return (1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
record.zi_freq = atoi(optarg);
|
||||
if (record.zi_freq < 1 || record.zi_freq > 100) {
|
||||
(void) fprintf(stderr, "frequency range must "
|
||||
"be in the range (0, 100]\n");
|
||||
return (1);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
return (0);
|
||||
case 'l':
|
||||
level = (int)strtol(optarg, &end, 10);
|
||||
if (*end != '\0') {
|
||||
(void) fprintf(stderr, "invalid level '%s': "
|
||||
"must be an integer\n", optarg);
|
||||
usage();
|
||||
return (1);
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
domount = 1;
|
||||
break;
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
case 'r':
|
||||
range = optarg;
|
||||
break;
|
||||
case 't':
|
||||
if ((type = name_to_type(optarg)) == TYPE_INVAL &&
|
||||
!MOS_TYPE(type)) {
|
||||
(void) fprintf(stderr, "invalid type '%s'\n",
|
||||
optarg);
|
||||
usage();
|
||||
return (1);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
flags |= ZINJECT_UNLOAD_SPA;
|
||||
break;
|
||||
case 'L':
|
||||
if ((label = name_to_type(optarg)) == TYPE_INVAL &&
|
||||
!LABEL_TYPE(type)) {
|
||||
(void) fprintf(stderr, "invalid label type "
|
||||
"'%s'\n", optarg);
|
||||
usage();
|
||||
return (1);
|
||||
}
|
||||
break;
|
||||
case ':':
|
||||
(void) fprintf(stderr, "option -%c requires an "
|
||||
"operand\n", optopt);
|
||||
usage();
|
||||
return (1);
|
||||
case '?':
|
||||
(void) fprintf(stderr, "invalid option '%c'\n",
|
||||
optopt);
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (cancel != NULL) {
|
||||
/*
|
||||
* '-c' is invalid with any other options.
|
||||
*/
|
||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||
level != 0) {
|
||||
(void) fprintf(stderr, "cancel (-c) incompatible with "
|
||||
"any other options\n");
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
if (argc != 0) {
|
||||
(void) fprintf(stderr, "extraneous argument to '-c'\n");
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
|
||||
if (strcmp(cancel, "all") == 0) {
|
||||
return (cancel_all_handlers());
|
||||
} else {
|
||||
int id = (int)strtol(cancel, &end, 10);
|
||||
if (*end != '\0') {
|
||||
(void) fprintf(stderr, "invalid handle id '%s':"
|
||||
" must be an integer or 'all'\n", cancel);
|
||||
usage();
|
||||
return (1);
|
||||
}
|
||||
return (cancel_handler(id));
|
||||
}
|
||||
}
|
||||
|
||||
if (device != NULL) {
|
||||
/*
|
||||
* Device (-d) injection uses a completely different mechanism
|
||||
* for doing injection, so handle it separately here.
|
||||
*/
|
||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||
level != 0) {
|
||||
(void) fprintf(stderr, "device (-d) incompatible with "
|
||||
"data error injection\n");
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
|
||||
if (argc != 1) {
|
||||
(void) fprintf(stderr, "device (-d) injection requires "
|
||||
"a single pool name\n");
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
|
||||
(void) strcpy(pool, argv[0]);
|
||||
dataset[0] = '\0';
|
||||
|
||||
if (error == ECKSUM) {
|
||||
(void) fprintf(stderr, "device error type must be "
|
||||
"'io' or 'nxio'\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (translate_device(pool, device, label, &record) != 0)
|
||||
return (1);
|
||||
if (!error)
|
||||
error = ENXIO;
|
||||
} else if (raw != NULL) {
|
||||
if (range != NULL || type != TYPE_INVAL || level != 0) {
|
||||
(void) fprintf(stderr, "raw (-b) format with "
|
||||
"any other options\n");
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
|
||||
if (argc != 1) {
|
||||
(void) fprintf(stderr, "raw (-b) format expects a "
|
||||
"single pool name\n");
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
|
||||
(void) strcpy(pool, argv[0]);
|
||||
dataset[0] = '\0';
|
||||
|
||||
if (error == ENXIO) {
|
||||
(void) fprintf(stderr, "data error type must be "
|
||||
"'checksum' or 'io'\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (translate_raw(raw, &record) != 0)
|
||||
return (1);
|
||||
if (!error)
|
||||
error = EIO;
|
||||
} else if (type == TYPE_INVAL) {
|
||||
if (flags == 0) {
|
||||
(void) fprintf(stderr, "at least one of '-b', '-d', "
|
||||
"'-t', '-a', or '-u' must be specified\n");
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
|
||||
if (argc == 1 && (flags & ZINJECT_UNLOAD_SPA)) {
|
||||
(void) strcpy(pool, argv[0]);
|
||||
dataset[0] = '\0';
|
||||
} else if (argc != 0) {
|
||||
(void) fprintf(stderr, "extraneous argument for "
|
||||
"'-f'\n");
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
|
||||
flags |= ZINJECT_NULL;
|
||||
} else {
|
||||
if (argc != 1) {
|
||||
(void) fprintf(stderr, "missing object\n");
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
|
||||
if (error == ENXIO) {
|
||||
(void) fprintf(stderr, "data error type must be "
|
||||
"'checksum' or 'io'\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (translate_record(type, argv[0], range, level, &record, pool,
|
||||
dataset) != 0)
|
||||
return (1);
|
||||
if (!error)
|
||||
error = EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is pool-wide metadata, unmount everything. The ioctl() will
|
||||
* unload the pool, so that we trigger spa-wide reopen of metadata next
|
||||
* time we access the pool.
|
||||
*/
|
||||
if (dataset[0] != '\0' && domount) {
|
||||
if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
|
||||
return (1);
|
||||
|
||||
if (zfs_unmount(zhp, NULL, 0) != 0)
|
||||
return (1);
|
||||
}
|
||||
|
||||
record.zi_error = error;
|
||||
|
||||
ret = register_handler(pool, flags, &record, quiet);
|
||||
|
||||
if (dataset[0] != '\0' && domount)
|
||||
ret = (zfs_mount(zhp, NULL, 0) != 0);
|
||||
|
||||
libzfs_fini(g_zfs);
|
||||
|
||||
return (ret);
|
||||
}
|
71
cddl/contrib/opensolaris/cmd/zinject/zinject.h
Normal file
71
cddl/contrib/opensolaris/cmd/zinject/zinject.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* 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]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _ZINJECT_H
|
||||
#define _ZINJECT_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <sys/zfs_ioctl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
TYPE_DATA, /* plain file contents */
|
||||
TYPE_DNODE, /* metadnode contents */
|
||||
TYPE_MOS, /* all MOS data */
|
||||
TYPE_MOSDIR, /* MOS object directory */
|
||||
TYPE_METASLAB, /* metaslab objects */
|
||||
TYPE_CONFIG, /* MOS config */
|
||||
TYPE_BPLIST, /* block pointer list */
|
||||
TYPE_SPACEMAP, /* space map objects */
|
||||
TYPE_ERRLOG, /* persistent error log */
|
||||
TYPE_LABEL_UBERBLOCK, /* label specific uberblock */
|
||||
TYPE_LABEL_NVLIST, /* label specific nvlist */
|
||||
TYPE_INVAL
|
||||
} err_type_t;
|
||||
|
||||
#define MOS_TYPE(t) \
|
||||
((t) >= TYPE_MOS && (t) < TYPE_LABEL_UBERBLOCK)
|
||||
|
||||
#define LABEL_TYPE(t) \
|
||||
((t) >= TYPE_LABEL_UBERBLOCK && (t) < TYPE_INVAL)
|
||||
|
||||
int translate_record(err_type_t type, const char *object, const char *range,
|
||||
int level, zinject_record_t *record, char *poolname, char *dataset);
|
||||
int translate_raw(const char *raw, zinject_record_t *record);
|
||||
int translate_device(const char *pool, const char *device,
|
||||
err_type_t label_type, zinject_record_t *record);
|
||||
void usage(void);
|
||||
|
||||
extern libzfs_handle_t *g_zfs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ZINJECT_H */
|
File diff suppressed because it is too large
Load Diff
@ -53,6 +53,7 @@ struct zpool_list {
|
||||
boolean_t zl_findall;
|
||||
uu_avl_t *zl_avl;
|
||||
uu_avl_pool_t *zl_pool;
|
||||
zprop_list_t **zl_proplist;
|
||||
};
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -81,6 +82,12 @@ add_pool(zpool_handle_t *zhp, void *data)
|
||||
node->zn_handle = zhp;
|
||||
uu_avl_node_init(node, &node->zn_avlnode, zlp->zl_pool);
|
||||
if (uu_avl_find(zlp->zl_avl, node, NULL, &idx) == NULL) {
|
||||
if (zlp->zl_proplist &&
|
||||
zpool_expand_proplist(zhp, zlp->zl_proplist) != 0) {
|
||||
zpool_close(zhp);
|
||||
free(node);
|
||||
return (-1);
|
||||
}
|
||||
uu_avl_insert(zlp->zl_avl, node, idx);
|
||||
} else {
|
||||
zpool_close(zhp);
|
||||
@ -98,7 +105,7 @@ add_pool(zpool_handle_t *zhp, void *data)
|
||||
* line.
|
||||
*/
|
||||
zpool_list_t *
|
||||
pool_list_get(int argc, char **argv, zpool_proplist_t **proplist, int *err)
|
||||
pool_list_get(int argc, char **argv, zprop_list_t **proplist, int *err)
|
||||
{
|
||||
zpool_list_t *zlp;
|
||||
|
||||
@ -114,6 +121,8 @@ pool_list_get(int argc, char **argv, zpool_proplist_t **proplist, int *err)
|
||||
UU_DEFAULT)) == NULL)
|
||||
zpool_no_memory();
|
||||
|
||||
zlp->zl_proplist = proplist;
|
||||
|
||||
if (argc == 0) {
|
||||
(void) zpool_iter(g_zfs, add_pool, zlp);
|
||||
zlp->zl_findall = B_TRUE;
|
||||
@ -123,13 +132,12 @@ pool_list_get(int argc, char **argv, zpool_proplist_t **proplist, int *err)
|
||||
for (i = 0; i < argc; i++) {
|
||||
zpool_handle_t *zhp;
|
||||
|
||||
if ((zhp = zpool_open_canfail(g_zfs,
|
||||
argv[i])) != NULL && add_pool(zhp, zlp) == 0) {
|
||||
if (proplist &&
|
||||
zpool_expand_proplist(zhp, proplist) != 0)
|
||||
if (zhp = zpool_open_canfail(g_zfs, argv[i])) {
|
||||
if (add_pool(zhp, zlp) != 0)
|
||||
*err = B_TRUE;
|
||||
} else
|
||||
} else {
|
||||
*err = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,7 +236,7 @@ pool_list_count(zpool_list_t *zlp)
|
||||
*/
|
||||
int
|
||||
for_each_pool(int argc, char **argv, boolean_t unavail,
|
||||
zpool_proplist_t **proplist, zpool_iter_f func, void *data)
|
||||
zprop_list_t **proplist, zpool_iter_f func, void *data)
|
||||
{
|
||||
zpool_list_t *list;
|
||||
int ret = 0;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -77,3 +77,28 @@ zpool_no_memory(void)
|
||||
gettext("internal error: out of memory\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of logs in supplied nvlist
|
||||
*/
|
||||
uint_t
|
||||
num_logs(nvlist_t *nv)
|
||||
{
|
||||
uint_t nlogs = 0;
|
||||
uint_t c, children;
|
||||
nvlist_t **child;
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
|
||||
&child, &children) != 0)
|
||||
return (0);
|
||||
|
||||
for (c = 0; c < children; c++) {
|
||||
uint64_t is_log = B_FALSE;
|
||||
|
||||
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
|
||||
&is_log);
|
||||
if (is_log)
|
||||
nlogs++;
|
||||
}
|
||||
return (nlogs);
|
||||
}
|
||||
|
@ -19,15 +19,13 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef ZPOOL_UTIL_H
|
||||
#define ZPOOL_UTIL_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <libnvpair.h>
|
||||
#include <libzfs.h>
|
||||
|
||||
@ -41,22 +39,24 @@ extern "C" {
|
||||
void *safe_malloc(size_t);
|
||||
char *safe_strdup(const char *);
|
||||
void zpool_no_memory(void);
|
||||
uint_t num_logs(nvlist_t *nv);
|
||||
|
||||
/*
|
||||
* Virtual device functions
|
||||
*/
|
||||
nvlist_t *make_root_vdev(nvlist_t *poolconfig, int force, int check_rep,
|
||||
boolean_t isreplace, int argc, char **argv);
|
||||
|
||||
nvlist_t *make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
|
||||
boolean_t isreplace, boolean_t dryrun, int argc, char **argv);
|
||||
|
||||
/*
|
||||
* Pool list functions
|
||||
*/
|
||||
int for_each_pool(int, char **, boolean_t unavail, zpool_proplist_t **,
|
||||
int for_each_pool(int, char **, boolean_t unavail, zprop_list_t **,
|
||||
zpool_iter_f, void *);
|
||||
|
||||
typedef struct zpool_list zpool_list_t;
|
||||
|
||||
zpool_list_t *pool_list_get(int, char **, zpool_proplist_t **, int *);
|
||||
zpool_list_t *pool_list_get(int, char **, zprop_list_t **, int *);
|
||||
void pool_list_update(zpool_list_t *);
|
||||
int pool_list_iter(zpool_list_t *, int unavail, zpool_iter_f, void *);
|
||||
void pool_list_free(zpool_list_t *);
|
||||
|
@ -20,12 +20,10 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
/*
|
||||
* Functions to convert between a list of vdevs and an nvlist representing the
|
||||
* configuration. Each entry in the list can be one of:
|
||||
@ -48,8 +46,8 @@
|
||||
* Hot spares are a special case, and passed down as an array of disk vdevs, at
|
||||
* the same level as the root of the vdev tree.
|
||||
*
|
||||
* The only function exported by this file is 'get_vdev_spec'. The function
|
||||
* performs several passes:
|
||||
* The only function exported by this file is 'make_root_vdev'. The
|
||||
* function performs several passes:
|
||||
*
|
||||
* 1. Construct the vdev specification. Performs syntax validation and
|
||||
* makes sure each device is valid.
|
||||
@ -59,6 +57,7 @@
|
||||
* 3. Check for replication errors if the 'force' flag is not specified.
|
||||
* validates that the replication level is consistent across the
|
||||
* entire pool.
|
||||
* 4. Call libzfs to label any whole disks with an EFI label.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
@ -76,8 +75,6 @@
|
||||
#include <sys/mntent.h>
|
||||
#include <libgeom.h>
|
||||
|
||||
#include <libzfs.h>
|
||||
|
||||
#include "zpool_util.h"
|
||||
|
||||
/*
|
||||
@ -111,53 +108,105 @@ vdev_error(const char *fmt, ...)
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate a GEOM provider.
|
||||
* Check that a file is valid. All we can do in this case is check that it's
|
||||
* not in use by another pool, and not in use by swap.
|
||||
*/
|
||||
static int
|
||||
check_file(const char *file, boolean_t force, boolean_t isspare)
|
||||
{
|
||||
char *name;
|
||||
int fd;
|
||||
int ret = 0;
|
||||
int err;
|
||||
pool_state_t state;
|
||||
boolean_t inuse;
|
||||
|
||||
#if 0
|
||||
if (dm_inuse_swap(file, &err)) {
|
||||
if (err)
|
||||
libdiskmgt_error(err);
|
||||
else
|
||||
vdev_error(gettext("%s is currently used by swap. "
|
||||
"Please see swap(1M).\n"), file);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((fd = open(file, O_RDONLY)) < 0)
|
||||
return (0);
|
||||
|
||||
if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) == 0 && inuse) {
|
||||
const char *desc;
|
||||
|
||||
switch (state) {
|
||||
case POOL_STATE_ACTIVE:
|
||||
desc = gettext("active");
|
||||
break;
|
||||
|
||||
case POOL_STATE_EXPORTED:
|
||||
desc = gettext("exported");
|
||||
break;
|
||||
|
||||
case POOL_STATE_POTENTIALLY_ACTIVE:
|
||||
desc = gettext("potentially active");
|
||||
break;
|
||||
|
||||
default:
|
||||
desc = gettext("unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow hot spares to be shared between pools.
|
||||
*/
|
||||
if (state == POOL_STATE_SPARE && isspare)
|
||||
return (0);
|
||||
|
||||
if (state == POOL_STATE_ACTIVE ||
|
||||
state == POOL_STATE_SPARE || !force) {
|
||||
switch (state) {
|
||||
case POOL_STATE_SPARE:
|
||||
vdev_error(gettext("%s is reserved as a hot "
|
||||
"spare for pool %s\n"), file, name);
|
||||
break;
|
||||
default:
|
||||
vdev_error(gettext("%s is part of %s pool "
|
||||
"'%s'\n"), file, desc, name);
|
||||
break;
|
||||
}
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
check_provider(const char *name, boolean_t force, boolean_t isspare)
|
||||
{
|
||||
struct gmesh mesh;
|
||||
struct gclass *mp;
|
||||
struct ggeom *gp;
|
||||
struct gprovider *pp;
|
||||
int rv;
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
/* XXX: What to do with isspare? */
|
||||
if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV) - 1) != 0)
|
||||
snprintf(path, sizeof(path), "%s%s", _PATH_DEV, name);
|
||||
else
|
||||
strlcpy(path, name, sizeof(path));
|
||||
|
||||
if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
|
||||
name += sizeof(_PATH_DEV) - 1;
|
||||
|
||||
rv = geom_gettree(&mesh);
|
||||
assert(rv == 0);
|
||||
|
||||
pp = NULL;
|
||||
LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
|
||||
LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
|
||||
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
|
||||
if (strcmp(pp->lg_name, name) == 0)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
rv = -1;
|
||||
if (pp == NULL)
|
||||
vdev_error("no such provider %s\n", name);
|
||||
else {
|
||||
int acr, acw, ace;
|
||||
|
||||
VERIFY(sscanf(pp->lg_mode, "r%dw%de%d", &acr, &acw, &ace) == 3);
|
||||
if (acw == 0 && ace == 0)
|
||||
rv = 0;
|
||||
else
|
||||
vdev_error("%s is in use (%s)\n", name, pp->lg_mode);
|
||||
}
|
||||
geom_deletetree(&mesh);
|
||||
return (rv);
|
||||
return (check_file(path, force, isspare));
|
||||
}
|
||||
|
||||
/*
|
||||
* By "whole disk" we mean an entire physical disk (something we can
|
||||
* label, toggle the write cache on, etc.) as opposed to the full
|
||||
* capacity of a pseudo-device such as lofi or did. We act as if we
|
||||
* are labeling the disk, which should be a pretty good test of whether
|
||||
* it's a viable device or not. Returns B_TRUE if it is and B_FALSE if
|
||||
* it isn't.
|
||||
*/
|
||||
static boolean_t
|
||||
is_provider(const char *name)
|
||||
is_whole_disk(const char *name)
|
||||
{
|
||||
int fd;
|
||||
|
||||
@ -167,8 +216,8 @@ is_provider(const char *name)
|
||||
return (B_TRUE);
|
||||
}
|
||||
return (B_FALSE);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a leaf vdev. Determine if this is a GEOM provider.
|
||||
* Valid forms for a leaf vdev are:
|
||||
@ -176,25 +225,81 @@ is_provider(const char *name)
|
||||
* /dev/xxx Complete path to a GEOM provider
|
||||
* xxx Shorthand for /dev/xxx
|
||||
*/
|
||||
nvlist_t *
|
||||
make_leaf_vdev(const char *arg)
|
||||
static nvlist_t *
|
||||
make_leaf_vdev(const char *arg, uint64_t is_log)
|
||||
{
|
||||
char ident[DISK_IDENT_SIZE], path[MAXPATHLEN];
|
||||
char path[MAXPATHLEN];
|
||||
struct stat64 statbuf;
|
||||
nvlist_t *vdev = NULL;
|
||||
char *type = NULL;
|
||||
boolean_t wholedisk = B_FALSE;
|
||||
|
||||
if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
|
||||
strlcpy(path, arg, sizeof (path));
|
||||
else
|
||||
snprintf(path, sizeof (path), "%s%s", _PATH_DEV, arg);
|
||||
/*
|
||||
* Determine what type of vdev this is, and put the full path into
|
||||
* 'path'. We detect whether this is a device of file afterwards by
|
||||
* checking the st_mode of the file.
|
||||
*/
|
||||
if (arg[0] == '/') {
|
||||
/*
|
||||
* Complete device or file path. Exact type is determined by
|
||||
* examining the file descriptor afterwards.
|
||||
*/
|
||||
wholedisk = is_whole_disk(arg);
|
||||
if (!wholedisk && (stat64(arg, &statbuf) != 0)) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("cannot open '%s': %s\n"),
|
||||
arg, strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (is_provider(path))
|
||||
(void) strlcpy(path, arg, sizeof (path));
|
||||
} else {
|
||||
/*
|
||||
* This may be a short path for a device, or it could be total
|
||||
* gibberish. Check to see if it's a known device in
|
||||
* /dev/dsk/. As part of this check, see if we've been given a
|
||||
* an entire disk (minus the slice number).
|
||||
*/
|
||||
if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
|
||||
strlcpy(path, arg, sizeof (path));
|
||||
else
|
||||
snprintf(path, sizeof (path), "%s%s", _PATH_DEV, arg);
|
||||
wholedisk = is_whole_disk(path);
|
||||
if (!wholedisk && (stat64(path, &statbuf) != 0)) {
|
||||
/*
|
||||
* If we got ENOENT, then the user gave us
|
||||
* gibberish, so try to direct them with a
|
||||
* reasonable error message. Otherwise,
|
||||
* regurgitate strerror() since it's the best we
|
||||
* can do.
|
||||
*/
|
||||
if (errno == ENOENT) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("cannot open '%s': no such "
|
||||
"GEOM provider\n"), arg);
|
||||
(void) fprintf(stderr,
|
||||
gettext("must be a full path or "
|
||||
"shorthand device name\n"));
|
||||
return (NULL);
|
||||
} else {
|
||||
(void) fprintf(stderr,
|
||||
gettext("cannot open '%s': %s\n"),
|
||||
path, strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether this is a device or a file.
|
||||
*/
|
||||
if (wholedisk) {
|
||||
type = VDEV_TYPE_DISK;
|
||||
else {
|
||||
} else if (S_ISREG(statbuf.st_mode)) {
|
||||
type = VDEV_TYPE_FILE;
|
||||
} else {
|
||||
(void) fprintf(stderr, gettext("cannot use '%s': must be a "
|
||||
"GEOM provider\n"), path);
|
||||
"GEOM provider or regular file\n"), path);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -206,6 +311,7 @@ make_leaf_vdev(const char *arg)
|
||||
verify(nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) == 0);
|
||||
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
|
||||
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
|
||||
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_LOG, is_log) == 0);
|
||||
if (strcmp(type, VDEV_TYPE_DISK) == 0)
|
||||
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
|
||||
(uint64_t)B_FALSE) == 0);
|
||||
@ -267,12 +373,14 @@ typedef struct replication_level {
|
||||
uint64_t zprl_parity;
|
||||
} replication_level_t;
|
||||
|
||||
#define ZPOOL_FUZZ (16 * 1024 * 1024)
|
||||
|
||||
/*
|
||||
* Given a list of toplevel vdevs, return the current replication level. If
|
||||
* the config is inconsistent, then NULL is returned. If 'fatal' is set, then
|
||||
* an error message will be displayed for each self-inconsistent vdev.
|
||||
*/
|
||||
replication_level_t *
|
||||
static replication_level_t *
|
||||
get_replication(nvlist_t *nvroot, boolean_t fatal)
|
||||
{
|
||||
nvlist_t **top;
|
||||
@ -291,10 +399,20 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
||||
|
||||
lastrep.zprl_type = NULL;
|
||||
for (t = 0; t < toplevels; t++) {
|
||||
uint64_t is_log = B_FALSE;
|
||||
|
||||
nv = top[t];
|
||||
|
||||
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
|
||||
/*
|
||||
* For separate logs we ignore the top level vdev replication
|
||||
* constraints.
|
||||
*/
|
||||
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
|
||||
if (is_log)
|
||||
continue;
|
||||
|
||||
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE,
|
||||
&type) == 0);
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
|
||||
&child, &children) != 0) {
|
||||
/*
|
||||
@ -328,7 +446,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
||||
}
|
||||
|
||||
/*
|
||||
* The 'dontreport' variable indicatest that we've
|
||||
* The 'dontreport' variable indicates that we've
|
||||
* already reported an error for this spec, so don't
|
||||
* bother doing it again.
|
||||
*/
|
||||
@ -349,7 +467,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
||||
ZPOOL_CONFIG_TYPE, &childtype) == 0);
|
||||
|
||||
/*
|
||||
* If this is a a replacing or spare vdev, then
|
||||
* If this is a replacing or spare vdev, then
|
||||
* get the real first child of the vdev.
|
||||
*/
|
||||
if (strcmp(childtype,
|
||||
@ -409,22 +527,30 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
||||
*/
|
||||
if ((fd = open(path, O_RDONLY)) >= 0) {
|
||||
err = fstat64(fd, &statbuf);
|
||||
if (err == 0 &&
|
||||
S_ISCHR(statbuf.st_mode)) {
|
||||
err = ioctl(fd, DIOCGMEDIASIZE,
|
||||
&statbuf.st_size);
|
||||
}
|
||||
(void) close(fd);
|
||||
} else {
|
||||
err = stat64(path, &statbuf);
|
||||
}
|
||||
|
||||
if (err != 0 || statbuf.st_size == 0)
|
||||
continue;
|
||||
|
||||
size = statbuf.st_size;
|
||||
|
||||
/*
|
||||
* Also check the size of each device. If they
|
||||
* differ, then report an error.
|
||||
* Also make sure that devices and
|
||||
* slices have a consistent size. If
|
||||
* they differ by a significant amount
|
||||
* (~16MB) then report an error.
|
||||
*/
|
||||
if (!dontreport && vdev_size != -1ULL &&
|
||||
size != vdev_size) {
|
||||
if (!dontreport &&
|
||||
(vdev_size != -1ULL &&
|
||||
(labs(size - vdev_size) >
|
||||
ZPOOL_FUZZ))) {
|
||||
if (ret != NULL)
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
@ -506,9 +632,11 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
||||
* has a consistent replication level, then we ignore any errors. Otherwise,
|
||||
* report any difference between the two.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
check_replication(nvlist_t *config, nvlist_t *newroot)
|
||||
{
|
||||
nvlist_t **child;
|
||||
uint_t children;
|
||||
replication_level_t *current = NULL, *new;
|
||||
int ret;
|
||||
|
||||
@ -524,6 +652,23 @@ check_replication(nvlist_t *config, nvlist_t *newroot)
|
||||
if ((current = get_replication(nvroot, B_FALSE)) == NULL)
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* for spares there may be no children, and therefore no
|
||||
* replication level to check
|
||||
*/
|
||||
if ((nvlist_lookup_nvlist_array(newroot, ZPOOL_CONFIG_CHILDREN,
|
||||
&child, &children) != 0) || (children == 0)) {
|
||||
free(current);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If all we have is logs then there's no replication level to check.
|
||||
*/
|
||||
if (num_logs(newroot) == children) {
|
||||
free(current);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the replication level of the new vdev spec, reporting any
|
||||
@ -621,7 +766,7 @@ is_spare(nvlist_t *config, const char *path)
|
||||
* Go through and find any devices that are in use. We rely on libdiskmgt for
|
||||
* the majority of this task.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
check_in_use(nvlist_t *config, nvlist_t *nv, int force, int isreplacing,
|
||||
int isspare)
|
||||
{
|
||||
@ -653,6 +798,9 @@ check_in_use(nvlist_t *config, nvlist_t *nv, int force, int isreplacing,
|
||||
if (strcmp(type, VDEV_TYPE_DISK) == 0)
|
||||
ret = check_provider(path, force, isspare);
|
||||
|
||||
if (strcmp(type, VDEV_TYPE_FILE) == 0)
|
||||
ret = check_file(path, force, isspare);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -668,10 +816,17 @@ check_in_use(nvlist_t *config, nvlist_t *nv, int force, int isreplacing,
|
||||
isreplacing, B_TRUE)) != 0)
|
||||
return (ret);
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
|
||||
&child, &children) == 0)
|
||||
for (c = 0; c < children; c++)
|
||||
if ((ret = check_in_use(config, child[c], force,
|
||||
isreplacing, B_FALSE)) != 0)
|
||||
return (ret);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
const char *
|
||||
static const char *
|
||||
is_grouping(const char *type, int *mindev)
|
||||
{
|
||||
if (strcmp(type, "raidz") == 0 || strcmp(type, "raidz1") == 0) {
|
||||
@ -698,6 +853,18 @@ is_grouping(const char *type, int *mindev)
|
||||
return (VDEV_TYPE_SPARE);
|
||||
}
|
||||
|
||||
if (strcmp(type, "log") == 0) {
|
||||
if (mindev != NULL)
|
||||
*mindev = 1;
|
||||
return (VDEV_TYPE_LOG);
|
||||
}
|
||||
|
||||
if (strcmp(type, "cache") == 0) {
|
||||
if (mindev != NULL)
|
||||
*mindev = 1;
|
||||
return (VDEV_TYPE_L2CACHE);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -710,14 +877,21 @@ is_grouping(const char *type, int *mindev)
|
||||
nvlist_t *
|
||||
construct_spec(int argc, char **argv)
|
||||
{
|
||||
nvlist_t *nvroot, *nv, **top, **spares;
|
||||
int t, toplevels, mindev, nspares;
|
||||
nvlist_t *nvroot, *nv, **top, **spares, **l2cache;
|
||||
int t, toplevels, mindev, nspares, nlogs, nl2cache;
|
||||
const char *type;
|
||||
uint64_t is_log;
|
||||
boolean_t seen_logs;
|
||||
|
||||
top = NULL;
|
||||
toplevels = 0;
|
||||
spares = NULL;
|
||||
l2cache = NULL;
|
||||
nspares = 0;
|
||||
nlogs = 0;
|
||||
nl2cache = 0;
|
||||
is_log = B_FALSE;
|
||||
seen_logs = B_FALSE;
|
||||
|
||||
while (argc > 0) {
|
||||
nv = NULL;
|
||||
@ -730,12 +904,56 @@ construct_spec(int argc, char **argv)
|
||||
nvlist_t **child = NULL;
|
||||
int c, children = 0;
|
||||
|
||||
if (strcmp(type, VDEV_TYPE_SPARE) == 0 &&
|
||||
spares != NULL) {
|
||||
(void) fprintf(stderr, gettext("invalid vdev "
|
||||
"specification: 'spare' can be "
|
||||
"specified only once\n"));
|
||||
return (NULL);
|
||||
if (strcmp(type, VDEV_TYPE_SPARE) == 0) {
|
||||
if (spares != NULL) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid vdev "
|
||||
"specification: 'spare' can be "
|
||||
"specified only once\n"));
|
||||
return (NULL);
|
||||
}
|
||||
is_log = B_FALSE;
|
||||
}
|
||||
|
||||
if (strcmp(type, VDEV_TYPE_LOG) == 0) {
|
||||
if (seen_logs) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid vdev "
|
||||
"specification: 'log' can be "
|
||||
"specified only once\n"));
|
||||
return (NULL);
|
||||
}
|
||||
seen_logs = B_TRUE;
|
||||
is_log = B_TRUE;
|
||||
argc--;
|
||||
argv++;
|
||||
/*
|
||||
* A log is not a real grouping device.
|
||||
* We just set is_log and continue.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(type, VDEV_TYPE_L2CACHE) == 0) {
|
||||
if (l2cache != NULL) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid vdev "
|
||||
"specification: 'cache' can be "
|
||||
"specified only once\n"));
|
||||
return (NULL);
|
||||
}
|
||||
is_log = B_FALSE;
|
||||
}
|
||||
|
||||
if (is_log) {
|
||||
if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid vdev "
|
||||
"specification: unsupported 'log' "
|
||||
"device: %s\n"), type);
|
||||
return (NULL);
|
||||
}
|
||||
nlogs++;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; c++) {
|
||||
@ -746,7 +964,8 @@ construct_spec(int argc, char **argv)
|
||||
children * sizeof (nvlist_t *));
|
||||
if (child == NULL)
|
||||
zpool_no_memory();
|
||||
if ((nv = make_leaf_vdev(argv[c])) == NULL)
|
||||
if ((nv = make_leaf_vdev(argv[c], B_FALSE))
|
||||
== NULL)
|
||||
return (NULL);
|
||||
child[children - 1] = nv;
|
||||
}
|
||||
@ -765,11 +984,17 @@ construct_spec(int argc, char **argv)
|
||||
spares = child;
|
||||
nspares = children;
|
||||
continue;
|
||||
} else if (strcmp(type, VDEV_TYPE_L2CACHE) == 0) {
|
||||
l2cache = child;
|
||||
nl2cache = children;
|
||||
continue;
|
||||
} else {
|
||||
verify(nvlist_alloc(&nv, NV_UNIQUE_NAME,
|
||||
0) == 0);
|
||||
verify(nvlist_add_string(nv, ZPOOL_CONFIG_TYPE,
|
||||
type) == 0);
|
||||
verify(nvlist_add_uint64(nv,
|
||||
ZPOOL_CONFIG_IS_LOG, is_log) == 0);
|
||||
if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
|
||||
verify(nvlist_add_uint64(nv,
|
||||
ZPOOL_CONFIG_NPARITY,
|
||||
@ -788,8 +1013,10 @@ construct_spec(int argc, char **argv)
|
||||
* We have a device. Pass off to make_leaf_vdev() to
|
||||
* construct the appropriate nvlist describing the vdev.
|
||||
*/
|
||||
if ((nv = make_leaf_vdev(argv[0])) == NULL)
|
||||
if ((nv = make_leaf_vdev(argv[0], is_log)) == NULL)
|
||||
return (NULL);
|
||||
if (is_log)
|
||||
nlogs++;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
@ -801,13 +1028,19 @@ construct_spec(int argc, char **argv)
|
||||
top[toplevels - 1] = nv;
|
||||
}
|
||||
|
||||
if (toplevels == 0 && nspares == 0) {
|
||||
if (toplevels == 0 && nspares == 0 && nl2cache == 0) {
|
||||
(void) fprintf(stderr, gettext("invalid vdev "
|
||||
"specification: at least one toplevel vdev must be "
|
||||
"specified\n"));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (seen_logs && nlogs == 0) {
|
||||
(void) fprintf(stderr, gettext("invalid vdev specification: "
|
||||
"log requires at least 1 device\n"));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, create nvroot and add all top-level vdevs to it.
|
||||
*/
|
||||
@ -819,18 +1052,26 @@ construct_spec(int argc, char **argv)
|
||||
if (nspares != 0)
|
||||
verify(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
|
||||
spares, nspares) == 0);
|
||||
if (nl2cache != 0)
|
||||
verify(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
|
||||
l2cache, nl2cache) == 0);
|
||||
|
||||
for (t = 0; t < toplevels; t++)
|
||||
nvlist_free(top[t]);
|
||||
for (t = 0; t < nspares; t++)
|
||||
nvlist_free(spares[t]);
|
||||
for (t = 0; t < nl2cache; t++)
|
||||
nvlist_free(l2cache[t]);
|
||||
if (spares)
|
||||
free(spares);
|
||||
if (l2cache)
|
||||
free(l2cache);
|
||||
free(top);
|
||||
|
||||
return (nvroot);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get and validate the contents of the given vdev specification. This ensures
|
||||
* that the nvlist returned is well-formed, that all the devices exist, and that
|
||||
@ -842,11 +1083,11 @@ construct_spec(int argc, char **argv)
|
||||
* added, even if they appear in use.
|
||||
*/
|
||||
nvlist_t *
|
||||
make_root_vdev(nvlist_t *poolconfig, int force, int check_rep,
|
||||
boolean_t isreplacing, int argc, char **argv)
|
||||
make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
|
||||
boolean_t isreplacing, boolean_t dryrun, int argc, char **argv)
|
||||
{
|
||||
nvlist_t *newroot;
|
||||
|
||||
nvlist_t *poolconfig = NULL;
|
||||
is_force = force;
|
||||
|
||||
/*
|
||||
@ -857,6 +1098,9 @@ make_root_vdev(nvlist_t *poolconfig, int force, int check_rep,
|
||||
if ((newroot = construct_spec(argc, argv)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (zhp && ((poolconfig = zpool_get_config(zhp, NULL)) == NULL))
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* Validate each device to make sure that its not shared with another
|
||||
* subsystem. We do this even if 'force' is set, because there are some
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,7 +39,7 @@ extern "C" {
|
||||
|
||||
#if defined(__STDC__)
|
||||
#if __STDC_VERSION__ - 0 >= 199901L
|
||||
extern void __assert_c99(const char *, const char *, int, const char *);
|
||||
extern void __assert(const char *, const char *, int);
|
||||
#else
|
||||
extern void __assert(const char *, const char *, int);
|
||||
#endif /* __STDC_VERSION__ - 0 >= 199901L */
|
||||
@ -70,8 +70,7 @@ extern void _assert();
|
||||
|
||||
#if defined(__STDC__)
|
||||
#if __STDC_VERSION__ - 0 >= 199901L
|
||||
#define assert(EX) (void)((EX) || \
|
||||
(__assert_c99(#EX, __FILE__, __LINE__, __func__), 0))
|
||||
#define assert(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
|
||||
#else
|
||||
#define assert(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
|
||||
#endif /* __STDC_VERSION__ - 0 >= 199901L */
|
||||
|
@ -2,9 +2,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* 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.
|
||||
@ -20,11 +19,10 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
/* Libintl is a library of advanced internationalization functions. */
|
||||
|
||||
#ifndef _LIBINTL_H
|
||||
#define _LIBINTL_H
|
||||
@ -63,6 +61,9 @@ typedef long wchar_t;
|
||||
|
||||
#define TEXTDOMAINMAX 256
|
||||
|
||||
#define __GNU_GETTEXT_SUPPORTED_REVISION(m) \
|
||||
((((m) == 0) || ((m) == 1)) ? 1 : -1)
|
||||
|
||||
#ifdef __STDC__
|
||||
extern char *dcgettext(const char *, const char *, const int);
|
||||
extern char *dgettext(const char *, const char *);
|
||||
|
@ -2,9 +2,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* 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.
|
||||
@ -19,8 +18,9 @@
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -81,12 +81,12 @@ typedef lwp_cond_t cond_t;
|
||||
* Because we have to deal with C++, we cannot redefine this one as that one.
|
||||
*/
|
||||
typedef struct _rwlock {
|
||||
int32_t readers; /* -1 == writer else # of readers */
|
||||
int32_t readers; /* rwstate word */
|
||||
uint16_t type;
|
||||
uint16_t magic;
|
||||
mutex_t mutex; /* used to indicate ownership */
|
||||
cond_t readercv; /* unused */
|
||||
cond_t writercv; /* unused */
|
||||
mutex_t mutex; /* used with process-shared rwlocks */
|
||||
cond_t readercv; /* used only to indicate ownership */
|
||||
cond_t writercv; /* used only to indicate ownership */
|
||||
} rwlock_t;
|
||||
|
||||
#ifdef __STDC__
|
||||
@ -111,6 +111,7 @@ int cond_signal(cond_t *);
|
||||
int cond_broadcast(cond_t *);
|
||||
int mutex_init(mutex_t *, int, void *);
|
||||
int mutex_destroy(mutex_t *);
|
||||
int mutex_consistent(mutex_t *);
|
||||
int mutex_lock(mutex_t *);
|
||||
int mutex_trylock(mutex_t *);
|
||||
int mutex_unlock(mutex_t *);
|
||||
@ -152,6 +153,7 @@ int cond_signal();
|
||||
int cond_broadcast();
|
||||
int mutex_init();
|
||||
int mutex_destroy();
|
||||
int mutex_consistent();
|
||||
int mutex_lock();
|
||||
int mutex_trylock();
|
||||
int mutex_unlock();
|
||||
|
@ -30,6 +30,7 @@
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <pthread_np.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
@ -52,6 +53,7 @@ typedef pthread_rwlock_t rwlock_t;
|
||||
#define mutex_lock(l) pthread_mutex_lock(l)
|
||||
#define mutex_trylock(l) pthread_mutex_trylock(l)
|
||||
#define mutex_unlock(l) pthread_mutex_unlock(l)
|
||||
#define mutex_owned(l) pthread_mutex_isowned_np(l)
|
||||
#define rwlock_init(l,f,a) pthread_rwlock_init(l,NULL)
|
||||
#define rwlock_destroy(l) pthread_rwlock_destroy(l)
|
||||
#define rw_rdlock(l) pthread_rwlock_rdlock(l)
|
||||
|
@ -868,15 +868,19 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
|
||||
/*
|
||||
* We may have already processed this object file in an earlier linker
|
||||
* invocation. Check to see if the present instruction sequence matches
|
||||
* the one we would install.
|
||||
* the one we would install below.
|
||||
*/
|
||||
if (isenabled) {
|
||||
if (ip[0] == DT_OP_CLR_O0)
|
||||
if (ip[0] == DT_OP_NOP) {
|
||||
(*off) += sizeof (ip[0]);
|
||||
return (0);
|
||||
}
|
||||
} else {
|
||||
if (DT_IS_RESTORE(ip[1])) {
|
||||
if (ip[0] == DT_OP_RET)
|
||||
if (ip[0] == DT_OP_RET) {
|
||||
(*off) += sizeof (ip[0]);
|
||||
return (0);
|
||||
}
|
||||
} else if (DT_IS_MOV_O7(ip[1])) {
|
||||
if (DT_IS_RETL(ip[0]))
|
||||
return (0);
|
||||
@ -910,7 +914,17 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ip[0] = DT_OP_CLR_O0;
|
||||
|
||||
/*
|
||||
* On SPARC, we take advantage of the fact that the first
|
||||
* argument shares the same register as for the return value.
|
||||
* The macro handles the work of zeroing that register so we
|
||||
* don't need to do anything special here. We instrument the
|
||||
* instruction in the delay slot as we'll need to modify the
|
||||
* return register after that instruction has been emulated.
|
||||
*/
|
||||
ip[0] = DT_OP_NOP;
|
||||
(*off) += sizeof (ip[0]);
|
||||
} else {
|
||||
/*
|
||||
* If the call is followed by a restore, it's a tail call so
|
||||
@ -919,11 +933,16 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
|
||||
* so change the call to a retl-like instruction that returns
|
||||
* to that register value + 8 (rather than the typical %o7 +
|
||||
* 8); the delay slot instruction is left, but should have no
|
||||
* effect. Otherwise we change the call to be a nop. In the
|
||||
* first and the last case we adjust the offset to land on what
|
||||
* was once the delay slot of the call so we correctly get all
|
||||
* the arguments as they would have been passed in a normal
|
||||
* function call.
|
||||
* effect. Otherwise we change the call to be a nop. We
|
||||
* identify the subsequent instruction as the probe point in
|
||||
* all but the leaf tail-call case to ensure that arguments to
|
||||
* the probe are complete and consistent. An astute, though
|
||||
* largely hypothetical, observer would note that there is the
|
||||
* possibility of a false-positive probe firing if the function
|
||||
* contained a branch to the instruction in the delay slot of
|
||||
* the call. Fixing this would require significant in-kernel
|
||||
* modifications, and isn't worth doing until we see it in the
|
||||
* wild.
|
||||
*/
|
||||
if (DT_IS_RESTORE(ip[1])) {
|
||||
ip[0] = DT_OP_RET;
|
||||
|
@ -115,8 +115,9 @@
|
||||
#define DT_VERS_1_5 DT_VERSION_NUMBER(1, 5, 0)
|
||||
#define DT_VERS_1_6 DT_VERSION_NUMBER(1, 6, 0)
|
||||
#define DT_VERS_1_6_1 DT_VERSION_NUMBER(1, 6, 1)
|
||||
#define DT_VERS_LATEST DT_VERS_1_6_1
|
||||
#define DT_VERS_STRING "Sun D 1.6.1"
|
||||
#define DT_VERS_1_6_2 DT_VERSION_NUMBER(1, 6, 2)
|
||||
#define DT_VERS_LATEST DT_VERS_1_6_2
|
||||
#define DT_VERS_STRING "Sun D 1.6.2"
|
||||
|
||||
const dt_version_t _dtrace_versions[] = {
|
||||
DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
|
||||
@ -130,6 +131,7 @@ const dt_version_t _dtrace_versions[] = {
|
||||
DT_VERS_1_5, /* D API 1.5 Solaris Express 7/07 */
|
||||
DT_VERS_1_6, /* D API 1.6 */
|
||||
DT_VERS_1_6_1, /* D API 1.6.1 */
|
||||
DT_VERS_1_6_2, /* D API 1.6.2 */
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -955,7 +955,8 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop)
|
||||
}
|
||||
|
||||
struct ps_prochandle *
|
||||
dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv)
|
||||
dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
|
||||
proc_child_func *pcf, void *child_arg)
|
||||
{
|
||||
dt_proc_hash_t *dph = dtp->dt_procs;
|
||||
dt_proc_t *dpr;
|
||||
@ -981,7 +982,7 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv)
|
||||
#else
|
||||
(void) proc_clearflags(dpr->dpr_proc, PR_RLC);
|
||||
(void) proc_setflags(dpr->dpr_proc, PR_KLC);
|
||||
if ((err = proc_create(file, argv, &dpr->dpr_proc)) != 0)
|
||||
if ((err = proc_create(file, argv, pcf, child_arg, &dpr->dpr_proc)) != 0)
|
||||
return (dt_proc_error(dtp, dpr,
|
||||
"failed to execute %s: %s\n", file, strerror(err)));
|
||||
dpr->dpr_hdl = dtp;
|
||||
@ -1183,10 +1184,11 @@ dt_proc_hash_destroy(dtrace_hdl_t *dtp)
|
||||
}
|
||||
|
||||
struct ps_prochandle *
|
||||
dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv)
|
||||
dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
|
||||
proc_child_func *pcf, void *child_arg)
|
||||
{
|
||||
dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");
|
||||
struct ps_prochandle *P = dt_proc_create(dtp, file, argv);
|
||||
struct ps_prochandle *P = dt_proc_create(dtp, file, argv, pcf, child_arg);
|
||||
|
||||
if (P != NULL && idp != NULL && idp->di_id == 0)
|
||||
#if defined(sun)
|
||||
|
@ -99,7 +99,7 @@ typedef struct dt_proc_hash {
|
||||
} dt_proc_hash_t;
|
||||
|
||||
extern struct ps_prochandle *dt_proc_create(dtrace_hdl_t *,
|
||||
const char *, char *const *);
|
||||
const char *, char *const *, proc_child_func *, void *);
|
||||
|
||||
extern struct ps_prochandle *dt_proc_grab(dtrace_hdl_t *, pid_t, int, int);
|
||||
extern void dt_proc_release(dtrace_hdl_t *, struct ps_prochandle *);
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -436,8 +436,13 @@ dt_header_decl(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
|
||||
if (fprintf(infop->dthi_out, ");\n") < 0)
|
||||
return (dt_set_errno(dtp, errno));
|
||||
|
||||
if (fprintf(infop->dthi_out, "extern int "
|
||||
"__dtraceenabled_%s___%s(void);\n", infop->dthi_pfname, fname) < 0)
|
||||
if (fprintf(infop->dthi_out,
|
||||
"#ifndef\t__sparc\n"
|
||||
"extern int __dtraceenabled_%s___%s(void);\n"
|
||||
"#else\n"
|
||||
"extern int __dtraceenabled_%s___%s(long);\n"
|
||||
"#endif\n",
|
||||
infop->dthi_pfname, fname, infop->dthi_pfname, fname) < 0)
|
||||
return (dt_set_errno(dtp, errno));
|
||||
|
||||
return (0);
|
||||
@ -499,13 +504,20 @@ dt_header_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
|
||||
return (dt_set_errno(dtp, errno));
|
||||
|
||||
if (!infop->dthi_empty) {
|
||||
if (fprintf(infop->dthi_out, "#define\t%s_%s_ENABLED() \\\n",
|
||||
infop->dthi_pmname, mname) < 0)
|
||||
return (dt_set_errno(dtp, errno));
|
||||
|
||||
if (fprintf(infop->dthi_out, "\t__dtraceenabled_%s___%s()\n",
|
||||
if (fprintf(infop->dthi_out,
|
||||
"#ifndef\t__sparc\n"
|
||||
"#define\t%s_%s_ENABLED() \\\n"
|
||||
"\t__dtraceenabled_%s___%s()\n"
|
||||
"#else\n"
|
||||
"#define\t%s_%s_ENABLED() \\\n"
|
||||
"\t__dtraceenabled_%s___%s(0)\n"
|
||||
"#endif\n",
|
||||
infop->dthi_pmname, mname,
|
||||
infop->dthi_pfname, fname,
|
||||
infop->dthi_pmname, mname,
|
||||
infop->dthi_pfname, fname) < 0)
|
||||
return (dt_set_errno(dtp, errno));
|
||||
|
||||
} else {
|
||||
if (fprintf(infop->dthi_out, "#define\t%s_%s_ENABLED() (0)\n",
|
||||
infop->dthi_pmname, mname) < 0)
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <gelf.h>
|
||||
#include <libproc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -413,7 +414,7 @@ extern int dtrace_aggregate_walk_valvarrevsorted(dtrace_hdl_t *,
|
||||
*/
|
||||
|
||||
extern struct ps_prochandle *dtrace_proc_create(dtrace_hdl_t *,
|
||||
const char *, char *const *);
|
||||
const char *, char *const *, proc_child_func *, void *);
|
||||
|
||||
extern struct ps_prochandle *dtrace_proc_grab(dtrace_hdl_t *, pid_t, int);
|
||||
extern void dtrace_proc_release(dtrace_hdl_t *, struct ps_prochandle *);
|
||||
|
@ -2,9 +2,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* 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.
|
||||
@ -20,12 +19,13 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <strings.h>
|
||||
#include "libnvpair.h"
|
||||
@ -137,6 +137,12 @@ nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth)
|
||||
(void) fprintf(fp, " 0x%llx", (u_longlong_t)val);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_DOUBLE: {
|
||||
double val;
|
||||
(void) nvpair_value_double(nvp, &val);
|
||||
(void) fprintf(fp, " 0x%llf", val);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_STRING: {
|
||||
char *val;
|
||||
(void) nvpair_value_string(nvp, &val);
|
||||
@ -264,3 +270,348 @@ nvlist_print(FILE *fp, nvlist_t *nvl)
|
||||
{
|
||||
nvlist_print_with_indent(fp, nvl, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if string 'value' matches 'nvp' value. The 'value' string is
|
||||
* converted, depending on the type of 'nvp', prior to match. For numeric
|
||||
* types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
|
||||
* is an array type, 'ai' is the index into the array against which we are
|
||||
* checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
|
||||
* in a regex_t compilation of value in 'value_regex' to trigger regular
|
||||
* expression string match instead of simple strcmp().
|
||||
*
|
||||
* Return 1 on match, 0 on no-match, and -1 on error. If the error is
|
||||
* related to value syntax error and 'ep' is non-NULL, *ep will point into
|
||||
* the 'value' string at the location where the error exists.
|
||||
*
|
||||
* NOTE: It may be possible to move the non-regex_t version of this into
|
||||
* common code used by library/kernel/boot.
|
||||
*/
|
||||
int
|
||||
nvpair_value_match_regex(nvpair_t *nvp, int ai,
|
||||
char *value, regex_t *value_regex, char **ep)
|
||||
{
|
||||
char *evalue;
|
||||
uint_t a_len;
|
||||
int sr;
|
||||
|
||||
if (ep)
|
||||
*ep = NULL;
|
||||
|
||||
if ((nvp == NULL) || (value == NULL))
|
||||
return (-1); /* error fail match - invalid args */
|
||||
|
||||
/* make sure array and index combination make sense */
|
||||
if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
|
||||
(!nvpair_type_is_array(nvp) && (ai >= 0)))
|
||||
return (-1); /* error fail match - bad index */
|
||||
|
||||
/* non-string values should be single 'chunk' */
|
||||
if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
|
||||
(nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
|
||||
value += strspn(value, " \t");
|
||||
evalue = value + strcspn(value, " \t");
|
||||
if (*evalue) {
|
||||
if (ep)
|
||||
*ep = evalue;
|
||||
return (-1); /* error fail match - syntax */
|
||||
}
|
||||
}
|
||||
|
||||
sr = EOF;
|
||||
switch (nvpair_type(nvp)) {
|
||||
case DATA_TYPE_STRING: {
|
||||
char *val;
|
||||
|
||||
/* check string value for match */
|
||||
if (nvpair_value_string(nvp, &val) == 0) {
|
||||
if (value_regex) {
|
||||
if (regexec(value_regex, val,
|
||||
(size_t)0, NULL, 0) == 0)
|
||||
return (1); /* match */
|
||||
} else {
|
||||
if (strcmp(value, val) == 0)
|
||||
return (1); /* match */
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_STRING_ARRAY: {
|
||||
char **val_array;
|
||||
|
||||
/* check indexed string value of array for match */
|
||||
if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
|
||||
(ai < a_len)) {
|
||||
if (value_regex) {
|
||||
if (regexec(value_regex, val_array[ai],
|
||||
(size_t)0, NULL, 0) == 0)
|
||||
return (1);
|
||||
} else {
|
||||
if (strcmp(value, val_array[ai]) == 0)
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_BYTE: {
|
||||
uchar_t val, val_arg;
|
||||
|
||||
/* scanf uchar_t from value and check for match */
|
||||
sr = sscanf(value, "%c", &val_arg);
|
||||
if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
|
||||
(val == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_BYTE_ARRAY: {
|
||||
uchar_t *val_array, val_arg;
|
||||
|
||||
|
||||
/* check indexed value of array for match */
|
||||
sr = sscanf(value, "%c", &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
|
||||
(ai < a_len) &&
|
||||
(val_array[ai] == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_INT8: {
|
||||
int8_t val, val_arg;
|
||||
|
||||
/* scanf int8_t from value and check for match */
|
||||
sr = sscanf(value, "%"SCNi8, &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_int8(nvp, &val) == 0) &&
|
||||
(val == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_INT8_ARRAY: {
|
||||
int8_t *val_array, val_arg;
|
||||
|
||||
/* check indexed value of array for match */
|
||||
sr = sscanf(value, "%"SCNi8, &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
|
||||
(ai < a_len) &&
|
||||
(val_array[ai] == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_UINT8: {
|
||||
uint8_t val, val_arg;
|
||||
|
||||
/* scanf uint8_t from value and check for match */
|
||||
sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_uint8(nvp, &val) == 0) &&
|
||||
(val == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_UINT8_ARRAY: {
|
||||
uint8_t *val_array, val_arg;
|
||||
|
||||
/* check indexed value of array for match */
|
||||
sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
|
||||
(ai < a_len) &&
|
||||
(val_array[ai] == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_INT16: {
|
||||
int16_t val, val_arg;
|
||||
|
||||
/* scanf int16_t from value and check for match */
|
||||
sr = sscanf(value, "%"SCNi16, &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_int16(nvp, &val) == 0) &&
|
||||
(val == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_INT16_ARRAY: {
|
||||
int16_t *val_array, val_arg;
|
||||
|
||||
/* check indexed value of array for match */
|
||||
sr = sscanf(value, "%"SCNi16, &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
|
||||
(ai < a_len) &&
|
||||
(val_array[ai] == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_UINT16: {
|
||||
uint16_t val, val_arg;
|
||||
|
||||
/* scanf uint16_t from value and check for match */
|
||||
sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_uint16(nvp, &val) == 0) &&
|
||||
(val == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_UINT16_ARRAY: {
|
||||
uint16_t *val_array, val_arg;
|
||||
|
||||
/* check indexed value of array for match */
|
||||
sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
|
||||
(ai < a_len) &&
|
||||
(val_array[ai] == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_INT32: {
|
||||
int32_t val, val_arg;
|
||||
|
||||
/* scanf int32_t from value and check for match */
|
||||
sr = sscanf(value, "%"SCNi32, &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_int32(nvp, &val) == 0) &&
|
||||
(val == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_INT32_ARRAY: {
|
||||
int32_t *val_array, val_arg;
|
||||
|
||||
/* check indexed value of array for match */
|
||||
sr = sscanf(value, "%"SCNi32, &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
|
||||
(ai < a_len) &&
|
||||
(val_array[ai] == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_UINT32: {
|
||||
uint32_t val, val_arg;
|
||||
|
||||
/* scanf uint32_t from value and check for match */
|
||||
sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_uint32(nvp, &val) == 0) &&
|
||||
(val == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_UINT32_ARRAY: {
|
||||
uint32_t *val_array, val_arg;
|
||||
|
||||
/* check indexed value of array for match */
|
||||
sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
|
||||
(ai < a_len) &&
|
||||
(val_array[ai] == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_INT64: {
|
||||
int64_t val, val_arg;
|
||||
|
||||
/* scanf int64_t from value and check for match */
|
||||
sr = sscanf(value, "%"SCNi64, &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_int64(nvp, &val) == 0) &&
|
||||
(val == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_INT64_ARRAY: {
|
||||
int64_t *val_array, val_arg;
|
||||
|
||||
/* check indexed value of array for match */
|
||||
sr = sscanf(value, "%"SCNi64, &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
|
||||
(ai < a_len) &&
|
||||
(val_array[ai] == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_UINT64: {
|
||||
uint64_t val_arg, val;
|
||||
|
||||
/* scanf uint64_t from value and check for match */
|
||||
sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_uint64(nvp, &val) == 0) &&
|
||||
(val == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_UINT64_ARRAY: {
|
||||
uint64_t *val_array, val_arg;
|
||||
|
||||
/* check indexed value of array for match */
|
||||
sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
|
||||
(ai < a_len) &&
|
||||
(val_array[ai] == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_BOOLEAN_VALUE: {
|
||||
boolean_t val, val_arg;
|
||||
|
||||
/* scanf boolean_t from value and check for match */
|
||||
sr = sscanf(value, "%"SCNi32, &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_boolean_value(nvp, &val) == 0) &&
|
||||
(val == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_BOOLEAN_ARRAY: {
|
||||
boolean_t *val_array, val_arg;
|
||||
|
||||
/* check indexed value of array for match */
|
||||
sr = sscanf(value, "%"SCNi32, &val_arg);
|
||||
if ((sr == 1) &&
|
||||
(nvpair_value_boolean_array(nvp,
|
||||
&val_array, &a_len) == 0) &&
|
||||
(ai < a_len) &&
|
||||
(val_array[ai] == val_arg))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE_HRTIME:
|
||||
case DATA_TYPE_NVLIST:
|
||||
case DATA_TYPE_NVLIST_ARRAY:
|
||||
case DATA_TYPE_BOOLEAN:
|
||||
case DATA_TYPE_DOUBLE:
|
||||
case DATA_TYPE_UNKNOWN:
|
||||
default:
|
||||
/*
|
||||
* unknown/unsupported data type
|
||||
*/
|
||||
return (-1); /* error fail match */
|
||||
}
|
||||
|
||||
/*
|
||||
* check to see if sscanf failed conversion, return approximate
|
||||
* pointer to problem
|
||||
*/
|
||||
if (sr != 1) {
|
||||
if (ep)
|
||||
*ep = value;
|
||||
return (-1); /* error fail match - syntax */
|
||||
}
|
||||
|
||||
return (0); /* fail match */
|
||||
}
|
||||
|
||||
int
|
||||
nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
|
||||
{
|
||||
return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
|
||||
}
|
||||
|
@ -2,9 +2,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* 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.
|
||||
@ -20,7 +19,7 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -32,12 +31,15 @@
|
||||
#include <sys/nvpair.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <regex.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void nvlist_print(FILE *, nvlist_t *);
|
||||
int nvpair_value_match(nvpair_t *, int, char *, char **);
|
||||
int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *, char **);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -2,9 +2,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* 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.
|
||||
@ -20,15 +19,13 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _LIBUUTIL_H
|
||||
#define _LIBUUTIL_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <solaris.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
@ -149,6 +146,7 @@ extern int uu_open_tmp(const char *dir, uint_t uflags);
|
||||
/*PRINTFLIKE1*/
|
||||
extern char *uu_msprintf(const char *format, ...);
|
||||
extern void *uu_zalloc(size_t);
|
||||
extern char *uu_strdup(const char *);
|
||||
extern void uu_free(void *);
|
||||
|
||||
/*
|
||||
|
@ -2,9 +2,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* 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.
|
||||
@ -21,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -30,16 +29,6 @@
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <solaris.h>
|
||||
|
||||
/*
|
||||
* We don't bind to the internal libc interfaces if this is a
|
||||
* native build.
|
||||
*/
|
||||
#ifndef NATIVE_BUILD
|
||||
#include "c_synonyms.h"
|
||||
#endif
|
||||
|
||||
#include <libuutil.h>
|
||||
#include <libuutil_impl.h>
|
||||
|
||||
|
@ -2,9 +2,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* 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.
|
||||
@ -20,12 +19,10 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include "libuutil_common.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
@ -54,6 +51,22 @@ uu_free(void *p)
|
||||
free(p);
|
||||
}
|
||||
|
||||
char *
|
||||
uu_strdup(const char *str)
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
if (str != NULL) {
|
||||
size_t sz;
|
||||
|
||||
sz = strlen(str) + 1;
|
||||
buf = uu_zalloc(sz);
|
||||
if (buf != NULL)
|
||||
(void) memcpy(buf, str, sz);
|
||||
}
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *
|
||||
uu_msprintf(const char *format, ...)
|
||||
{
|
||||
|
@ -19,7 +19,7 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -120,7 +120,8 @@ uu_avl_pool_destroy(uu_avl_pool_t *pp)
|
||||
UU_PTR_ENCODE(&pp->uap_null_avl)) {
|
||||
uu_panic("uu_avl_pool_destroy: Pool \"%.*s\" (%p) has "
|
||||
"outstanding avls, or is corrupt.\n",
|
||||
sizeof (pp->uap_name), pp->uap_name, pp);
|
||||
(int)sizeof (pp->uap_name), pp->uap_name,
|
||||
(void *)pp);
|
||||
}
|
||||
}
|
||||
(void) pthread_mutex_lock(&uu_apool_list_lock);
|
||||
@ -142,14 +143,14 @@ uu_avl_node_init(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp)
|
||||
if (offset + sizeof (*np) > pp->uap_objsize) {
|
||||
uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): "
|
||||
"offset %ld doesn't fit in object (size %ld)\n",
|
||||
base, np, pp, pp->uap_name, offset,
|
||||
pp->uap_objsize);
|
||||
base, (void *)np, (void *)pp, pp->uap_name,
|
||||
(long)offset, (long)pp->uap_objsize);
|
||||
}
|
||||
if (offset != pp->uap_nodeoffset) {
|
||||
uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): "
|
||||
"offset %ld doesn't match pool's offset (%ld)\n",
|
||||
base, np, pp, pp->uap_name, offset,
|
||||
pp->uap_objsize);
|
||||
base, (void *)np, (void *)pp, pp->uap_name,
|
||||
(long)offset, (long)pp->uap_objsize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,12 +167,12 @@ uu_avl_node_fini(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp)
|
||||
if (na[0] == DEAD_MARKER && na[1] == DEAD_MARKER) {
|
||||
uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): "
|
||||
"node already finied\n",
|
||||
base, np, pp, pp->uap_name);
|
||||
base, (void *)np, (void *)pp, pp->uap_name);
|
||||
}
|
||||
if (na[0] != POOL_TO_MARKER(pp) || na[1] != 0) {
|
||||
uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): "
|
||||
"node corrupt, in tree, or in different pool\n",
|
||||
base, np, pp, pp->uap_name);
|
||||
base, (void *)np, (void *)pp, pp->uap_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,12 +252,13 @@ uu_avl_destroy(uu_avl_t *ap)
|
||||
|
||||
if (ap->ua_debug) {
|
||||
if (avl_numnodes(&ap->ua_tree) != 0) {
|
||||
uu_panic("uu_avl_destroy(%p): tree not empty\n", ap);
|
||||
uu_panic("uu_avl_destroy(%p): tree not empty\n",
|
||||
(void *)ap);
|
||||
}
|
||||
if (ap->ua_null_walk.uaw_next != &ap->ua_null_walk ||
|
||||
ap->ua_null_walk.uaw_prev != &ap->ua_null_walk) {
|
||||
uu_panic("uu_avl_destroy(%p): outstanding walkers\n",
|
||||
ap);
|
||||
(void *)ap);
|
||||
}
|
||||
}
|
||||
(void) pthread_mutex_lock(&pp->uap_lock);
|
||||
@ -441,7 +443,7 @@ uu_avl_remove(uu_avl_t *ap, void *elem)
|
||||
(void) _avl_walk_advance(wp, ap);
|
||||
} else if (wp->uaw_next_result != NULL) {
|
||||
uu_panic("uu_avl_remove(%p, %p): active non-robust "
|
||||
"walker\n", ap, elem);
|
||||
"walker\n", (void *)ap, elem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -497,19 +499,19 @@ uu_avl_insert(uu_avl_t *ap, void *elem, uu_avl_index_t idx)
|
||||
if (na[1] != 0)
|
||||
uu_panic("uu_avl_insert(%p, %p, %p): node already "
|
||||
"in tree, or corrupt\n",
|
||||
ap, elem, idx);
|
||||
(void *)ap, elem, (void *)idx);
|
||||
if (na[0] == 0)
|
||||
uu_panic("uu_avl_insert(%p, %p, %p): node not "
|
||||
"initialized\n",
|
||||
ap, elem, idx);
|
||||
(void *)ap, elem, (void *)idx);
|
||||
if (na[0] != POOL_TO_MARKER(pp))
|
||||
uu_panic("uu_avl_insert(%p, %p, %p): node from "
|
||||
"other pool, or corrupt\n",
|
||||
ap, elem, idx);
|
||||
(void *)ap, elem, (void *)idx);
|
||||
|
||||
if (!INDEX_VALID(ap, idx))
|
||||
uu_panic("uu_avl_insert(%p, %p, %p): %s\n",
|
||||
ap, elem, idx,
|
||||
(void *)ap, elem, (void *)idx,
|
||||
INDEX_CHECK(idx)? "outdated index" :
|
||||
"invalid index");
|
||||
|
||||
@ -526,8 +528,8 @@ uu_avl_nearest_next(uu_avl_t *ap, uu_avl_index_t idx)
|
||||
{
|
||||
if (ap->ua_debug && !INDEX_VALID(ap, idx))
|
||||
uu_panic("uu_avl_nearest_next(%p, %p): %s\n",
|
||||
ap, idx, INDEX_CHECK(idx)? "outdated index" :
|
||||
"invalid index");
|
||||
(void *)ap, (void *)idx, INDEX_CHECK(idx)?
|
||||
"outdated index" : "invalid index");
|
||||
return (avl_nearest(&ap->ua_tree, INDEX_DECODE(idx), AVL_AFTER));
|
||||
}
|
||||
|
||||
@ -536,8 +538,8 @@ uu_avl_nearest_prev(uu_avl_t *ap, uu_avl_index_t idx)
|
||||
{
|
||||
if (ap->ua_debug && !INDEX_VALID(ap, idx))
|
||||
uu_panic("uu_avl_nearest_prev(%p, %p): %s\n",
|
||||
ap, idx, INDEX_CHECK(idx)? "outdated index" :
|
||||
"invalid index");
|
||||
(void *)ap, (void *)idx, INDEX_CHECK(idx)?
|
||||
"outdated index" : "invalid index");
|
||||
return (avl_nearest(&ap->ua_tree, INDEX_DECODE(idx), AVL_BEFORE));
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FACILITY_FMT "%s (%s): "
|
||||
|
||||
|
@ -2,9 +2,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* 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.
|
||||
@ -20,7 +19,7 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -117,7 +116,8 @@ uu_list_pool_destroy(uu_list_pool_t *pp)
|
||||
UU_PTR_ENCODE(&pp->ulp_null_list)) {
|
||||
uu_panic("uu_list_pool_destroy: Pool \"%.*s\" (%p) has "
|
||||
"outstanding lists, or is corrupt.\n",
|
||||
sizeof (pp->ulp_name), pp->ulp_name, pp);
|
||||
(int)sizeof (pp->ulp_name), pp->ulp_name,
|
||||
(void *)pp);
|
||||
}
|
||||
}
|
||||
(void) pthread_mutex_lock(&uu_lpool_list_lock);
|
||||
@ -139,14 +139,14 @@ uu_list_node_init(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp)
|
||||
if (offset + sizeof (*np) > pp->ulp_objsize) {
|
||||
uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): "
|
||||
"offset %ld doesn't fit in object (size %ld)\n",
|
||||
base, np, pp, pp->ulp_name, offset,
|
||||
pp->ulp_objsize);
|
||||
base, (void *)np, (void *)pp, pp->ulp_name,
|
||||
(long)offset, (long)pp->ulp_objsize);
|
||||
}
|
||||
if (offset != pp->ulp_nodeoffset) {
|
||||
uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): "
|
||||
"offset %ld doesn't match pool's offset (%ld)\n",
|
||||
base, np, pp, pp->ulp_name, offset,
|
||||
pp->ulp_objsize);
|
||||
base, (void *)np, (void *)pp, pp->ulp_name,
|
||||
(long)offset, (long)pp->ulp_objsize);
|
||||
}
|
||||
}
|
||||
np->uln_next = POOL_TO_MARKER(pp);
|
||||
@ -163,13 +163,13 @@ uu_list_node_fini(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp)
|
||||
np->uln_prev == NULL) {
|
||||
uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): "
|
||||
"node already finied\n",
|
||||
base, np_arg, pp, pp->ulp_name);
|
||||
base, (void *)np_arg, (void *)pp, pp->ulp_name);
|
||||
}
|
||||
if (np->uln_next != POOL_TO_MARKER(pp) ||
|
||||
np->uln_prev != NULL) {
|
||||
uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): "
|
||||
"node corrupt or on list\n",
|
||||
base, np_arg, pp, pp->ulp_name);
|
||||
base, (void *)np_arg, (void *)pp, pp->ulp_name);
|
||||
}
|
||||
}
|
||||
np->uln_next = NULL;
|
||||
@ -190,7 +190,7 @@ uu_list_create(uu_list_pool_t *pp, void *parent, uint32_t flags)
|
||||
if (pp->ulp_debug)
|
||||
uu_panic("uu_list_create(%p, ...): requested "
|
||||
"UU_LIST_SORTED, but pool has no comparison func\n",
|
||||
pp);
|
||||
(void *)pp);
|
||||
uu_set_error(UU_ERROR_NOT_SUPPORTED);
|
||||
return (NULL);
|
||||
}
|
||||
@ -236,16 +236,16 @@ uu_list_destroy(uu_list_t *lp)
|
||||
if (lp->ul_null_node.uln_next != &lp->ul_null_node ||
|
||||
lp->ul_null_node.uln_prev != &lp->ul_null_node) {
|
||||
uu_panic("uu_list_destroy(%p): list not empty\n",
|
||||
lp);
|
||||
(void *)lp);
|
||||
}
|
||||
if (lp->ul_numnodes != 0) {
|
||||
uu_panic("uu_list_destroy(%p): numnodes is nonzero, "
|
||||
"but list is empty\n", lp);
|
||||
"but list is empty\n", (void *)lp);
|
||||
}
|
||||
if (lp->ul_null_walk.ulw_next != &lp->ul_null_walk ||
|
||||
lp->ul_null_walk.ulw_prev != &lp->ul_null_walk) {
|
||||
uu_panic("uu_list_destroy(%p): outstanding walkers\n",
|
||||
lp);
|
||||
(void *)lp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,13 +266,14 @@ list_insert(uu_list_t *lp, uu_list_node_impl_t *np, uu_list_node_impl_t *prev,
|
||||
if (lp->ul_debug) {
|
||||
if (next->uln_prev != prev || prev->uln_next != next)
|
||||
uu_panic("insert(%p): internal error: %p and %p not "
|
||||
"neighbors\n", lp, next, prev);
|
||||
"neighbors\n", (void *)lp, (void *)next,
|
||||
(void *)prev);
|
||||
|
||||
if (np->uln_next != POOL_TO_MARKER(lp->ul_pool) ||
|
||||
np->uln_prev != NULL) {
|
||||
uu_panic("insert(%p): elem %p node %p corrupt, "
|
||||
"not initialized, or already in a list.\n",
|
||||
lp, NODE_TO_ELEM(lp, np), np);
|
||||
(void *)lp, NODE_TO_ELEM(lp, np), (void *)np);
|
||||
}
|
||||
/*
|
||||
* invalidate outstanding uu_list_index_ts.
|
||||
@ -299,12 +300,12 @@ uu_list_insert(uu_list_t *lp, void *elem, uu_list_index_t idx)
|
||||
if (lp->ul_debug) {
|
||||
if (!INDEX_VALID(lp, idx))
|
||||
uu_panic("uu_list_insert(%p, %p, %p): %s\n",
|
||||
lp, elem, idx,
|
||||
(void *)lp, elem, (void *)idx,
|
||||
INDEX_CHECK(idx)? "outdated index" :
|
||||
"invalid index");
|
||||
if (np->uln_prev == NULL)
|
||||
uu_panic("uu_list_insert(%p, %p, %p): out-of-date "
|
||||
"index\n", lp, elem, idx);
|
||||
"index\n", (void *)lp, elem, (void *)idx);
|
||||
}
|
||||
|
||||
list_insert(lp, ELEM_TO_NODE(lp, elem), np->uln_prev, np);
|
||||
@ -354,11 +355,12 @@ uu_list_nearest_next(uu_list_t *lp, uu_list_index_t idx)
|
||||
if (lp->ul_debug) {
|
||||
if (!INDEX_VALID(lp, idx))
|
||||
uu_panic("uu_list_nearest_next(%p, %p): %s\n",
|
||||
lp, idx, INDEX_CHECK(idx)? "outdated index" :
|
||||
(void *)lp, (void *)idx,
|
||||
INDEX_CHECK(idx)? "outdated index" :
|
||||
"invalid index");
|
||||
if (np->uln_prev == NULL)
|
||||
uu_panic("uu_list_nearest_next(%p, %p): out-of-date "
|
||||
"index\n", lp, idx);
|
||||
"index\n", (void *)lp, (void *)idx);
|
||||
}
|
||||
|
||||
if (np == &lp->ul_null_node)
|
||||
@ -378,11 +380,11 @@ uu_list_nearest_prev(uu_list_t *lp, uu_list_index_t idx)
|
||||
if (lp->ul_debug) {
|
||||
if (!INDEX_VALID(lp, idx))
|
||||
uu_panic("uu_list_nearest_prev(%p, %p): %s\n",
|
||||
lp, idx, INDEX_CHECK(idx)? "outdated index" :
|
||||
"invalid index");
|
||||
(void *)lp, (void *)idx, INDEX_CHECK(idx)?
|
||||
"outdated index" : "invalid index");
|
||||
if (np->uln_prev == NULL)
|
||||
uu_panic("uu_list_nearest_prev(%p, %p): out-of-date "
|
||||
"index\n", lp, idx);
|
||||
"index\n", (void *)lp, (void *)idx);
|
||||
}
|
||||
|
||||
if ((np = np->uln_prev) == &lp->ul_null_node)
|
||||
@ -409,6 +411,11 @@ list_walk_init(uu_list_walk_t *wp, uu_list_t *lp, uint32_t flags)
|
||||
wp->ulw_next_result = lp->ul_null_node.uln_prev;
|
||||
|
||||
if (lp->ul_debug || robust) {
|
||||
/*
|
||||
* Add this walker to the list's list of walkers so
|
||||
* uu_list_remove() can advance us if somebody tries to
|
||||
* remove ulw_next_result.
|
||||
*/
|
||||
wp->ulw_next = next = &lp->ul_null_walk;
|
||||
wp->ulw_prev = prev = next->ulw_prev;
|
||||
next->ulw_prev = wp;
|
||||
@ -538,7 +545,7 @@ uu_list_remove(uu_list_t *lp, void *elem)
|
||||
if (lp->ul_debug) {
|
||||
if (np->uln_prev == NULL)
|
||||
uu_panic("uu_list_remove(%p, %p): elem not on list\n",
|
||||
lp, elem);
|
||||
(void *)lp, elem);
|
||||
/*
|
||||
* invalidate outstanding uu_list_index_ts.
|
||||
*/
|
||||
@ -556,7 +563,7 @@ uu_list_remove(uu_list_t *lp, void *elem)
|
||||
(void) list_walk_advance(wp, lp);
|
||||
} else if (wp->ulw_next_result != NULL) {
|
||||
uu_panic("uu_list_remove(%p, %p): active non-robust "
|
||||
"walker\n", lp, elem);
|
||||
"walker\n", (void *)lp, elem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -578,8 +585,8 @@ uu_list_teardown(uu_list_t *lp, void **cookie)
|
||||
* XXX: disable list modification until list is empty
|
||||
*/
|
||||
if (lp->ul_debug && *cookie != NULL)
|
||||
uu_panic("uu_list_teardown(%p, %p): unexpected cookie\n", lp,
|
||||
cookie);
|
||||
uu_panic("uu_list_teardown(%p, %p): unexpected cookie\n",
|
||||
(void *)lp, (void *)cookie);
|
||||
|
||||
ep = uu_list_first(lp);
|
||||
if (ep)
|
||||
@ -599,12 +606,12 @@ uu_list_insert_before(uu_list_t *lp, void *target, void *elem)
|
||||
if (np->uln_prev == NULL)
|
||||
uu_panic("uu_list_insert_before(%p, %p, %p): %p is "
|
||||
"not currently on a list\n",
|
||||
lp, target, elem, target);
|
||||
(void *)lp, target, elem, target);
|
||||
}
|
||||
if (lp->ul_sorted) {
|
||||
if (lp->ul_debug)
|
||||
uu_panic("uu_list_insert_before(%p, ...): list is "
|
||||
"UU_LIST_SORTED\n", lp);
|
||||
"UU_LIST_SORTED\n", (void *)lp);
|
||||
uu_set_error(UU_ERROR_NOT_SUPPORTED);
|
||||
return (-1);
|
||||
}
|
||||
@ -625,12 +632,12 @@ uu_list_insert_after(uu_list_t *lp, void *target, void *elem)
|
||||
if (np->uln_prev == NULL)
|
||||
uu_panic("uu_list_insert_after(%p, %p, %p): %p is "
|
||||
"not currently on a list\n",
|
||||
lp, target, elem, target);
|
||||
(void *)lp, target, elem, target);
|
||||
}
|
||||
if (lp->ul_sorted) {
|
||||
if (lp->ul_debug)
|
||||
uu_panic("uu_list_insert_after(%p, ...): list is "
|
||||
"UU_LIST_SORTED\n", lp);
|
||||
"UU_LIST_SORTED\n", (void *)lp);
|
||||
uu_set_error(UU_ERROR_NOT_SUPPORTED);
|
||||
return (-1);
|
||||
}
|
||||
|
@ -20,21 +20,20 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _LIBZFS_H
|
||||
#define _LIBZFS_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <assert.h>
|
||||
#include <libnvpair.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/varargs.h>
|
||||
#include <sys/fs/zfs.h>
|
||||
#include <sys/avl.h>
|
||||
#include <sys/zfs_ioctl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -47,6 +46,7 @@ extern "C" {
|
||||
#define ZFS_MAXNAMELEN MAXNAMELEN
|
||||
#define ZPOOL_MAXNAMELEN MAXNAMELEN
|
||||
#define ZFS_MAXPROPLEN MAXPATHLEN
|
||||
#define ZPOOL_MAXPROPLEN MAXPATHLEN
|
||||
|
||||
/*
|
||||
* libzfs errors
|
||||
@ -99,9 +99,61 @@ enum {
|
||||
EZFS_POOL_NOTSUP, /* ops not supported for this type of pool */
|
||||
EZFS_POOL_INVALARG, /* invalid argument for this pool operation */
|
||||
EZFS_NAMETOOLONG, /* dataset name is too long */
|
||||
EZFS_OPENFAILED, /* open of device failed */
|
||||
EZFS_NOCAP, /* couldn't get capacity */
|
||||
EZFS_LABELFAILED, /* write of label failed */
|
||||
EZFS_ISCSISVCUNAVAIL, /* iscsi service unavailable */
|
||||
EZFS_BADWHO, /* invalid permission who */
|
||||
EZFS_BADPERM, /* invalid permission */
|
||||
EZFS_BADPERMSET, /* invalid permission set name */
|
||||
EZFS_NODELEGATION, /* delegated administration is disabled */
|
||||
EZFS_PERMRDONLY, /* pemissions are readonly */
|
||||
EZFS_UNSHARESMBFAILED, /* failed to unshare over smb */
|
||||
EZFS_SHARESMBFAILED, /* failed to share over smb */
|
||||
EZFS_BADCACHE, /* bad cache file */
|
||||
EZFS_ISL2CACHE, /* device is for the level 2 ARC */
|
||||
EZFS_VDEVNOTSUP, /* unsupported vdev type */
|
||||
EZFS_NOTSUP, /* ops not supported on this dataset */
|
||||
EZFS_ACTIVE_SPARE, /* pool has active shared spare devices */
|
||||
EZFS_UNKNOWN
|
||||
};
|
||||
|
||||
/*
|
||||
* The following data structures are all part
|
||||
* of the zfs_allow_t data structure which is
|
||||
* used for printing 'allow' permissions.
|
||||
* It is a linked list of zfs_allow_t's which
|
||||
* then contain avl tree's for user/group/sets/...
|
||||
* and each one of the entries in those trees have
|
||||
* avl tree's for the permissions they belong to and
|
||||
* whether they are local,descendent or local+descendent
|
||||
* permissions. The AVL trees are used primarily for
|
||||
* sorting purposes, but also so that we can quickly find
|
||||
* a given user and or permission.
|
||||
*/
|
||||
typedef struct zfs_perm_node {
|
||||
avl_node_t z_node;
|
||||
char z_pname[MAXPATHLEN];
|
||||
} zfs_perm_node_t;
|
||||
|
||||
typedef struct zfs_allow_node {
|
||||
avl_node_t z_node;
|
||||
char z_key[MAXPATHLEN]; /* name, such as joe */
|
||||
avl_tree_t z_localdescend; /* local+descendent perms */
|
||||
avl_tree_t z_local; /* local permissions */
|
||||
avl_tree_t z_descend; /* descendent permissions */
|
||||
} zfs_allow_node_t;
|
||||
|
||||
typedef struct zfs_allow {
|
||||
struct zfs_allow *z_next;
|
||||
char z_setpoint[MAXPATHLEN];
|
||||
avl_tree_t z_sets;
|
||||
avl_tree_t z_crperms;
|
||||
avl_tree_t z_user;
|
||||
avl_tree_t z_group;
|
||||
avl_tree_t z_everyone;
|
||||
} zfs_allow_t;
|
||||
|
||||
/*
|
||||
* Basic handle types
|
||||
*/
|
||||
@ -131,12 +183,9 @@ extern zpool_handle_t *zpool_open(libzfs_handle_t *, const char *);
|
||||
extern zpool_handle_t *zpool_open_canfail(libzfs_handle_t *, const char *);
|
||||
extern void zpool_close(zpool_handle_t *);
|
||||
extern const char *zpool_get_name(zpool_handle_t *);
|
||||
extern uint64_t zpool_get_guid(zpool_handle_t *);
|
||||
extern uint64_t zpool_get_space_used(zpool_handle_t *);
|
||||
extern uint64_t zpool_get_space_total(zpool_handle_t *);
|
||||
extern int zpool_get_root(zpool_handle_t *, char *, size_t);
|
||||
extern int zpool_get_state(zpool_handle_t *);
|
||||
extern uint64_t zpool_get_version(zpool_handle_t *);
|
||||
extern char *zpool_state_to_name(vdev_state_t, vdev_aux_t);
|
||||
extern void zpool_free_handles(libzfs_handle_t *);
|
||||
|
||||
/*
|
||||
* Iterate over all active pools in the system.
|
||||
@ -148,7 +197,7 @@ extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
|
||||
* Functions to create and destroy pools
|
||||
*/
|
||||
extern int zpool_create(libzfs_handle_t *, const char *, nvlist_t *,
|
||||
const char *);
|
||||
nvlist_t *, nvlist_t *);
|
||||
extern int zpool_destroy(zpool_handle_t *);
|
||||
extern int zpool_add(zpool_handle_t *, nvlist_t *);
|
||||
|
||||
@ -156,22 +205,33 @@ extern int zpool_add(zpool_handle_t *, nvlist_t *);
|
||||
* Functions to manipulate pool and vdev state
|
||||
*/
|
||||
extern int zpool_scrub(zpool_handle_t *, pool_scrub_type_t);
|
||||
extern int zpool_clear(zpool_handle_t *, const char *);
|
||||
|
||||
extern int zpool_vdev_online(zpool_handle_t *, const char *);
|
||||
extern int zpool_vdev_offline(zpool_handle_t *, const char *, int);
|
||||
extern int zpool_vdev_attach(zpool_handle_t *, const char *, const char *,
|
||||
nvlist_t *, int);
|
||||
extern int zpool_vdev_online(zpool_handle_t *, const char *, int,
|
||||
vdev_state_t *);
|
||||
extern int zpool_vdev_offline(zpool_handle_t *, const char *, boolean_t);
|
||||
extern int zpool_vdev_attach(zpool_handle_t *, const char *,
|
||||
const char *, nvlist_t *, int);
|
||||
extern int zpool_vdev_detach(zpool_handle_t *, const char *);
|
||||
extern int zpool_vdev_remove(zpool_handle_t *, const char *);
|
||||
extern int zpool_clear(zpool_handle_t *, const char *);
|
||||
extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *);
|
||||
|
||||
extern int zpool_vdev_fault(zpool_handle_t *, uint64_t);
|
||||
extern int zpool_vdev_degrade(zpool_handle_t *, uint64_t);
|
||||
extern int zpool_vdev_clear(zpool_handle_t *, uint64_t);
|
||||
|
||||
extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *,
|
||||
boolean_t *, boolean_t *);
|
||||
extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, char *);
|
||||
|
||||
/*
|
||||
* Functions to manage pool properties
|
||||
*/
|
||||
extern int zpool_set_prop(zpool_handle_t *, const char *, const char *);
|
||||
extern int zpool_get_prop(zpool_handle_t *, zfs_prop_t, char *,
|
||||
size_t proplen, zfs_source_t *);
|
||||
extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *,
|
||||
size_t proplen, zprop_source_t *);
|
||||
extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t,
|
||||
zprop_source_t *);
|
||||
|
||||
extern const char *zpool_prop_to_name(zpool_prop_t);
|
||||
extern const char *zpool_prop_values(zpool_prop_t);
|
||||
|
||||
@ -194,6 +254,11 @@ typedef enum {
|
||||
ZPOOL_STATUS_FAILING_DEV, /* device experiencing errors */
|
||||
ZPOOL_STATUS_VERSION_NEWER, /* newer on-disk version */
|
||||
ZPOOL_STATUS_HOSTID_MISMATCH, /* last accessed by another system */
|
||||
ZPOOL_STATUS_IO_FAILURE_WAIT, /* failed I/O, failmode 'wait' */
|
||||
ZPOOL_STATUS_IO_FAILURE_CONTINUE, /* failed I/O, failmode 'continue' */
|
||||
ZPOOL_STATUS_FAULTED_DEV_R, /* faulted device with replicas */
|
||||
ZPOOL_STATUS_FAULTED_DEV_NR, /* faulted device with no replicas */
|
||||
ZPOOL_STATUS_BAD_LOG, /* cannot read log chain(s) */
|
||||
|
||||
/*
|
||||
* The following are not faults per se, but still an error possibly
|
||||
@ -223,26 +288,39 @@ extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **);
|
||||
/*
|
||||
* Import and export functions
|
||||
*/
|
||||
extern int zpool_export(zpool_handle_t *);
|
||||
extern int zpool_export(zpool_handle_t *, boolean_t);
|
||||
extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
|
||||
const char *);
|
||||
char *altroot);
|
||||
extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,
|
||||
nvlist_t *, boolean_t);
|
||||
|
||||
/*
|
||||
* Search for pools to import
|
||||
*/
|
||||
extern nvlist_t *zpool_find_import(libzfs_handle_t *, int, char **);
|
||||
extern nvlist_t *zpool_find_import_cached(libzfs_handle_t *, const char *,
|
||||
char *, uint64_t);
|
||||
extern nvlist_t *zpool_find_import_byname(libzfs_handle_t *, int, char **,
|
||||
char *);
|
||||
extern nvlist_t *zpool_find_import_byguid(libzfs_handle_t *, int, char **,
|
||||
uint64_t);
|
||||
extern nvlist_t *zpool_find_import_activeok(libzfs_handle_t *, int, char **);
|
||||
|
||||
/*
|
||||
* Miscellaneous pool functions
|
||||
*/
|
||||
struct zfs_cmd;
|
||||
|
||||
extern char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *);
|
||||
extern int zpool_upgrade(zpool_handle_t *);
|
||||
extern int zpool_upgrade(zpool_handle_t *, uint64_t);
|
||||
extern int zpool_get_history(zpool_handle_t *, nvlist_t **);
|
||||
extern void zpool_log_history(libzfs_handle_t *, int, char **, const char *,
|
||||
boolean_t, boolean_t);
|
||||
extern void zpool_set_history_str(const char *subcommand, int argc,
|
||||
char **argv, char *history_str);
|
||||
extern int zpool_stage_history(libzfs_handle_t *, const char *);
|
||||
extern void zpool_obj_to_path(zpool_handle_t *, uint64_t, uint64_t, char *,
|
||||
size_t len);
|
||||
|
||||
extern int zfs_ioctl(libzfs_handle_t *, unsigned long, struct zfs_cmd *);
|
||||
extern int zpool_get_physpath(zpool_handle_t *, char *);
|
||||
/*
|
||||
* Basic handle manipulations. These functions do not create or destroy the
|
||||
* underlying datasets, only the references to them.
|
||||
@ -251,65 +329,84 @@ extern zfs_handle_t *zfs_open(libzfs_handle_t *, const char *, int);
|
||||
extern void zfs_close(zfs_handle_t *);
|
||||
extern zfs_type_t zfs_get_type(const zfs_handle_t *);
|
||||
extern const char *zfs_get_name(const zfs_handle_t *);
|
||||
extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *);
|
||||
|
||||
/*
|
||||
* Property management functions. Some functions are shared with the kernel,
|
||||
* and are found in sys/fs/zfs.h.
|
||||
*/
|
||||
|
||||
/*
|
||||
* zfs dataset property management
|
||||
*/
|
||||
extern const char *zfs_prop_default_string(zfs_prop_t);
|
||||
extern uint64_t zfs_prop_default_numeric(zfs_prop_t);
|
||||
extern const char *zfs_prop_column_name(zfs_prop_t);
|
||||
extern boolean_t zfs_prop_align_right(zfs_prop_t);
|
||||
|
||||
extern nvlist_t *zfs_valid_proplist(libzfs_handle_t *, zfs_type_t,
|
||||
nvlist_t *, uint64_t, zfs_handle_t *, const char *);
|
||||
|
||||
extern const char *zfs_prop_to_name(zfs_prop_t);
|
||||
extern int zfs_prop_set(zfs_handle_t *, const char *, const char *);
|
||||
extern int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t,
|
||||
zfs_source_t *, char *, size_t, boolean_t);
|
||||
zprop_source_t *, char *, size_t, boolean_t);
|
||||
extern int zfs_prop_get_numeric(zfs_handle_t *, zfs_prop_t, uint64_t *,
|
||||
zfs_source_t *, char *, size_t);
|
||||
zprop_source_t *, char *, size_t);
|
||||
extern uint64_t zfs_prop_get_int(zfs_handle_t *, zfs_prop_t);
|
||||
extern const char *zfs_prop_get_string(zfs_handle_t *, zfs_prop_t);
|
||||
extern int zfs_prop_inherit(zfs_handle_t *, const char *);
|
||||
extern const char *zfs_prop_values(zfs_prop_t);
|
||||
extern int zfs_prop_valid_for_type(zfs_prop_t, int);
|
||||
extern const char *zfs_prop_default_string(zfs_prop_t prop);
|
||||
extern uint64_t zfs_prop_default_numeric(zfs_prop_t);
|
||||
extern int zfs_prop_is_string(zfs_prop_t prop);
|
||||
extern const char *zfs_prop_column_name(zfs_prop_t);
|
||||
extern boolean_t zfs_prop_align_right(zfs_prop_t);
|
||||
extern void nicebool(int value, char *buf, size_t buflen);
|
||||
extern nvlist_t *zfs_get_user_props(zfs_handle_t *);
|
||||
|
||||
typedef struct zfs_proplist {
|
||||
zfs_prop_t pl_prop;
|
||||
typedef struct zprop_list {
|
||||
int pl_prop;
|
||||
char *pl_user_prop;
|
||||
struct zfs_proplist *pl_next;
|
||||
struct zprop_list *pl_next;
|
||||
boolean_t pl_all;
|
||||
size_t pl_width;
|
||||
boolean_t pl_fixed;
|
||||
} zfs_proplist_t;
|
||||
} zprop_list_t;
|
||||
|
||||
typedef zfs_proplist_t zpool_proplist_t;
|
||||
|
||||
extern int zfs_get_proplist(libzfs_handle_t *, char *, zfs_proplist_t **);
|
||||
extern int zpool_get_proplist(libzfs_handle_t *, char *, zpool_proplist_t **);
|
||||
extern int zfs_expand_proplist(zfs_handle_t *, zfs_proplist_t **);
|
||||
extern int zpool_expand_proplist(zpool_handle_t *, zpool_proplist_t **);
|
||||
extern void zfs_free_proplist(zfs_proplist_t *);
|
||||
extern nvlist_t *zfs_get_user_props(zfs_handle_t *);
|
||||
extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **);
|
||||
|
||||
#define ZFS_MOUNTPOINT_NONE "none"
|
||||
#define ZFS_MOUNTPOINT_LEGACY "legacy"
|
||||
|
||||
/*
|
||||
* Functions for printing properties from zfs/zpool
|
||||
* zpool property management
|
||||
*/
|
||||
typedef struct libzfs_get_cbdata {
|
||||
extern int zpool_expand_proplist(zpool_handle_t *, zprop_list_t **);
|
||||
extern const char *zpool_prop_default_string(zpool_prop_t);
|
||||
extern uint64_t zpool_prop_default_numeric(zpool_prop_t);
|
||||
extern const char *zpool_prop_column_name(zpool_prop_t);
|
||||
extern boolean_t zpool_prop_align_right(zpool_prop_t);
|
||||
|
||||
/*
|
||||
* Functions shared by zfs and zpool property management.
|
||||
*/
|
||||
extern int zprop_iter(zprop_func func, void *cb, boolean_t show_all,
|
||||
boolean_t ordered, zfs_type_t type);
|
||||
extern int zprop_get_list(libzfs_handle_t *, char *, zprop_list_t **,
|
||||
zfs_type_t);
|
||||
extern void zprop_free_list(zprop_list_t *);
|
||||
|
||||
/*
|
||||
* Functions for printing zfs or zpool properties
|
||||
*/
|
||||
typedef struct zprop_get_cbdata {
|
||||
int cb_sources;
|
||||
int cb_columns[4];
|
||||
int cb_colwidths[5];
|
||||
boolean_t cb_scripted;
|
||||
boolean_t cb_literal;
|
||||
boolean_t cb_first;
|
||||
zfs_proplist_t *cb_proplist;
|
||||
} libzfs_get_cbdata_t;
|
||||
zprop_list_t *cb_proplist;
|
||||
zfs_type_t cb_type;
|
||||
} zprop_get_cbdata_t;
|
||||
|
||||
void libzfs_print_one_property(const char *, libzfs_get_cbdata_t *,
|
||||
const char *, const char *, zfs_source_t, const char *);
|
||||
void zprop_print_one_property(const char *, zprop_get_cbdata_t *,
|
||||
const char *, const char *, zprop_source_t, const char *);
|
||||
|
||||
#define GET_COL_NAME 1
|
||||
#define GET_COL_PROPERTY 2
|
||||
@ -331,26 +428,61 @@ extern int zfs_iter_snapshots(zfs_handle_t *, zfs_iter_f, void *);
|
||||
*/
|
||||
extern int zfs_create(libzfs_handle_t *, const char *, zfs_type_t,
|
||||
nvlist_t *);
|
||||
extern int zfs_create_ancestors(libzfs_handle_t *, const char *);
|
||||
extern int zfs_destroy(zfs_handle_t *);
|
||||
extern int zfs_destroy_snaps(zfs_handle_t *, char *);
|
||||
extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *);
|
||||
extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t);
|
||||
extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, int);
|
||||
extern int zfs_rename(zfs_handle_t *, const char *, int);
|
||||
extern int zfs_send(zfs_handle_t *, const char *, int);
|
||||
extern int zfs_receive(libzfs_handle_t *, const char *, int, int, int,
|
||||
boolean_t, int);
|
||||
extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *);
|
||||
extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t);
|
||||
extern int zfs_rename(zfs_handle_t *, const char *, boolean_t);
|
||||
extern int zfs_send(zfs_handle_t *, const char *, const char *,
|
||||
boolean_t, boolean_t, boolean_t, boolean_t, int);
|
||||
extern int zfs_promote(zfs_handle_t *);
|
||||
|
||||
typedef struct recvflags {
|
||||
/* print informational messages (ie, -v was specified) */
|
||||
int verbose : 1;
|
||||
|
||||
/* the destination is a prefix, not the exact fs (ie, -d) */
|
||||
int isprefix : 1;
|
||||
|
||||
/* do not actually do the recv, just check if it would work (ie, -n) */
|
||||
int dryrun : 1;
|
||||
|
||||
/* rollback/destroy filesystems as necessary (eg, -F) */
|
||||
int force : 1;
|
||||
|
||||
/* set "canmount=off" on all modified filesystems */
|
||||
int canmountoff : 1;
|
||||
|
||||
/* byteswap flag is used internally; callers need not specify */
|
||||
int byteswap : 1;
|
||||
} recvflags_t;
|
||||
|
||||
extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t,
|
||||
int, avl_tree_t *);
|
||||
|
||||
/*
|
||||
* Miscellaneous functions.
|
||||
*/
|
||||
extern const char *zfs_type_to_name(zfs_type_t);
|
||||
extern void zfs_refresh_properties(zfs_handle_t *);
|
||||
extern int zfs_name_valid(const char *, zfs_type_t);
|
||||
extern int zfs_disable(zfs_handle_t *);
|
||||
extern int zfs_enable(zfs_handle_t *);
|
||||
extern zfs_handle_t *zfs_path_to_zhandle(libzfs_handle_t *, char *, zfs_type_t);
|
||||
extern boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *,
|
||||
zfs_type_t);
|
||||
extern int zfs_spa_version(zfs_handle_t *, int *);
|
||||
|
||||
/*
|
||||
* dataset permission functions.
|
||||
*/
|
||||
extern int zfs_perm_set(zfs_handle_t *, nvlist_t *);
|
||||
extern int zfs_perm_remove(zfs_handle_t *, nvlist_t *);
|
||||
extern int zfs_build_perms(zfs_handle_t *, char *, char *,
|
||||
zfs_deleg_who_type_t, zfs_deleg_inherit_t, nvlist_t **nvlist_t);
|
||||
extern int zfs_perm_get(zfs_handle_t *, zfs_allow_t **);
|
||||
extern void zfs_free_allows(zfs_allow_t *);
|
||||
extern void zfs_deleg_permissions(void);
|
||||
|
||||
/*
|
||||
* Mount support functions.
|
||||
@ -369,15 +501,27 @@ extern int zfs_share(zfs_handle_t *);
|
||||
extern int zfs_unshare(zfs_handle_t *);
|
||||
|
||||
/*
|
||||
* Protocol-specifc share support functions.
|
||||
* Protocol-specific share support functions.
|
||||
*/
|
||||
extern boolean_t zfs_is_shared_nfs(zfs_handle_t *, char **);
|
||||
extern boolean_t zfs_is_shared_smb(zfs_handle_t *, char **);
|
||||
extern int zfs_share_nfs(zfs_handle_t *);
|
||||
extern int zfs_share_smb(zfs_handle_t *);
|
||||
extern int zfs_shareall(zfs_handle_t *);
|
||||
extern int zfs_unshare_nfs(zfs_handle_t *, const char *);
|
||||
extern int zfs_unshare_smb(zfs_handle_t *, const char *);
|
||||
extern int zfs_unshareall_nfs(zfs_handle_t *);
|
||||
extern int zfs_unshareall_smb(zfs_handle_t *);
|
||||
extern int zfs_unshareall_bypath(zfs_handle_t *, const char *);
|
||||
extern int zfs_unshareall(zfs_handle_t *);
|
||||
extern boolean_t zfs_is_shared_iscsi(zfs_handle_t *);
|
||||
extern int zfs_share_iscsi(zfs_handle_t *);
|
||||
extern int zfs_unshare_iscsi(zfs_handle_t *);
|
||||
#ifdef TODO
|
||||
extern int zfs_iscsi_perm_check(libzfs_handle_t *, char *, ucred_t *);
|
||||
#endif
|
||||
extern int zfs_deleg_share_nfs(libzfs_handle_t *, char *, char *,
|
||||
void *, void *, int, zfs_share_op_t);
|
||||
|
||||
/*
|
||||
* FreeBSD-specific jail support function.
|
||||
@ -401,12 +545,6 @@ extern int zfs_jail(zfs_handle_t *, int, int);
|
||||
extern void zfs_nicenum(uint64_t, char *, size_t);
|
||||
extern int zfs_nicestrtonum(libzfs_handle_t *, const char *, uint64_t *);
|
||||
|
||||
/*
|
||||
* Pool destroy special. Remove the device information without destroying
|
||||
* the underlying dataset.
|
||||
*/
|
||||
extern int zfs_remove_link(zfs_handle_t *);
|
||||
|
||||
/*
|
||||
* Given a device or file, determine if it is part of a pool.
|
||||
*/
|
||||
@ -424,6 +562,9 @@ extern int zpool_read_label(int, nvlist_t **);
|
||||
extern int zpool_create_zvol_links(zpool_handle_t *);
|
||||
extern int zpool_remove_zvol_links(zpool_handle_t *);
|
||||
|
||||
/* is this zvol valid for use as a dump device? */
|
||||
extern int zvol_check_dump_config(char *);
|
||||
|
||||
/*
|
||||
* Enable and disable datasets within a pool by mounting/unmounting and
|
||||
* sharing/unsharing them.
|
||||
|
@ -20,12 +20,12 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Portions Copyright 2007 Ramprakash Jelari
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <libintl.h>
|
||||
#include <libuutil.h>
|
||||
#include <stddef.h>
|
||||
@ -65,18 +65,21 @@ typedef struct prop_changenode {
|
||||
int cn_shared;
|
||||
int cn_mounted;
|
||||
int cn_zoned;
|
||||
boolean_t cn_needpost; /* is postfix() needed? */
|
||||
uu_list_node_t cn_listnode;
|
||||
} prop_changenode_t;
|
||||
|
||||
struct prop_changelist {
|
||||
zfs_prop_t cl_prop;
|
||||
zfs_prop_t cl_realprop;
|
||||
zfs_prop_t cl_shareprop; /* used with sharenfs/sharesmb */
|
||||
uu_list_pool_t *cl_pool;
|
||||
uu_list_t *cl_list;
|
||||
boolean_t cl_waslegacy;
|
||||
boolean_t cl_allchildren;
|
||||
boolean_t cl_alldependents;
|
||||
int cl_flags;
|
||||
int cl_mflags; /* Mount flags */
|
||||
int cl_gflags; /* Gather request flags */
|
||||
boolean_t cl_haszonedchild;
|
||||
boolean_t cl_sorted;
|
||||
};
|
||||
@ -84,7 +87,8 @@ struct prop_changelist {
|
||||
/*
|
||||
* If the property is 'mountpoint', go through and unmount filesystems as
|
||||
* necessary. We don't do the same for 'sharenfs', because we can just re-share
|
||||
* with different options without interrupting service.
|
||||
* with different options without interrupting service. We do handle 'sharesmb'
|
||||
* since there may be old resource names that need to be removed.
|
||||
*/
|
||||
int
|
||||
changelist_prefix(prop_changelist_t *clp)
|
||||
@ -92,11 +96,19 @@ changelist_prefix(prop_changelist_t *clp)
|
||||
prop_changenode_t *cn;
|
||||
int ret = 0;
|
||||
|
||||
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT)
|
||||
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
|
||||
clp->cl_prop != ZFS_PROP_SHARESMB)
|
||||
return (0);
|
||||
|
||||
for (cn = uu_list_first(clp->cl_list); cn != NULL;
|
||||
cn = uu_list_next(clp->cl_list, cn)) {
|
||||
|
||||
/* if a previous loop failed, set the remaining to false */
|
||||
if (ret == -1) {
|
||||
cn->cn_needpost = B_FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are in the global zone, but this dataset is exported
|
||||
* to a local zone, do nothing.
|
||||
@ -114,8 +126,11 @@ changelist_prefix(prop_changelist_t *clp)
|
||||
(void) zfs_unshare_iscsi(cn->cn_handle);
|
||||
|
||||
if (zvol_remove_link(cn->cn_handle->zfs_hdl,
|
||||
cn->cn_handle->zfs_name) != 0)
|
||||
cn->cn_handle->zfs_name) != 0) {
|
||||
ret = -1;
|
||||
cn->cn_needpost = B_FALSE;
|
||||
(void) zfs_share_iscsi(cn->cn_handle);
|
||||
}
|
||||
break;
|
||||
|
||||
case ZFS_PROP_VOLSIZE:
|
||||
@ -126,10 +141,28 @@ changelist_prefix(prop_changelist_t *clp)
|
||||
(void) zfs_unshare_iscsi(cn->cn_handle);
|
||||
break;
|
||||
}
|
||||
} else if (zfs_unmount(cn->cn_handle, NULL, clp->cl_flags) != 0)
|
||||
ret = -1;
|
||||
} else {
|
||||
/*
|
||||
* Do the property specific processing.
|
||||
*/
|
||||
switch (clp->cl_prop) {
|
||||
case ZFS_PROP_MOUNTPOINT:
|
||||
if (zfs_unmount(cn->cn_handle, NULL,
|
||||
clp->cl_mflags) != 0) {
|
||||
ret = -1;
|
||||
cn->cn_needpost = B_FALSE;
|
||||
}
|
||||
break;
|
||||
case ZFS_PROP_SHARESMB:
|
||||
(void) zfs_unshare_smb(cn->cn_handle, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
(void) changelist_postfix(clp);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -147,7 +180,8 @@ changelist_postfix(prop_changelist_t *clp)
|
||||
{
|
||||
prop_changenode_t *cn;
|
||||
char shareopts[ZFS_MAXPROPLEN];
|
||||
int ret = 0;
|
||||
int errors = 0;
|
||||
libzfs_handle_t *hdl;
|
||||
|
||||
/*
|
||||
* If we're changing the mountpoint, attempt to destroy the underlying
|
||||
@ -162,12 +196,29 @@ changelist_postfix(prop_changelist_t *clp)
|
||||
if (clp->cl_prop == ZFS_PROP_MOUNTPOINT)
|
||||
remove_mountpoint(cn->cn_handle);
|
||||
|
||||
/*
|
||||
* It is possible that the changelist_prefix() used libshare
|
||||
* to unshare some entries. Since libshare caches data, an
|
||||
* attempt to reshare during postfix can fail unless libshare
|
||||
* is uninitialized here so that it will reinitialize later.
|
||||
*/
|
||||
if (cn->cn_handle != NULL) {
|
||||
hdl = cn->cn_handle->zfs_hdl;
|
||||
assert(hdl != NULL);
|
||||
zfs_uninit_libshare(hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
* We walk the datasets in reverse, because we want to mount any parent
|
||||
* datasets before mounting the children.
|
||||
* datasets before mounting the children. We walk all datasets even if
|
||||
* there are errors.
|
||||
*/
|
||||
for (cn = uu_list_last(clp->cl_list); cn != NULL;
|
||||
cn = uu_list_prev(clp->cl_list, cn)) {
|
||||
|
||||
boolean_t sharenfs;
|
||||
boolean_t sharesmb;
|
||||
|
||||
/*
|
||||
* If we are in the global zone, but this dataset is exported
|
||||
* to a local zone, do nothing.
|
||||
@ -175,6 +226,11 @@ changelist_postfix(prop_changelist_t *clp)
|
||||
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
|
||||
continue;
|
||||
|
||||
/* Only do post-processing if it's required */
|
||||
if (!cn->cn_needpost)
|
||||
continue;
|
||||
cn->cn_needpost = B_FALSE;
|
||||
|
||||
zfs_refresh_properties(cn->cn_handle);
|
||||
|
||||
if (ZFS_IS_VOLUME(cn->cn_handle)) {
|
||||
@ -185,7 +241,7 @@ changelist_postfix(prop_changelist_t *clp)
|
||||
if (clp->cl_realprop == ZFS_PROP_NAME &&
|
||||
zvol_create_link(cn->cn_handle->zfs_hdl,
|
||||
cn->cn_handle->zfs_name) != 0) {
|
||||
ret = -1;
|
||||
errors++;
|
||||
} else if (cn->cn_shared ||
|
||||
clp->cl_prop == ZFS_PROP_SHAREISCSI) {
|
||||
if (zfs_prop_get(cn->cn_handle,
|
||||
@ -193,43 +249,55 @@ changelist_postfix(prop_changelist_t *clp)
|
||||
sizeof (shareopts), NULL, NULL, 0,
|
||||
B_FALSE) == 0 &&
|
||||
strcmp(shareopts, "off") == 0) {
|
||||
ret = zfs_unshare_iscsi(cn->cn_handle);
|
||||
errors +=
|
||||
zfs_unshare_iscsi(cn->cn_handle);
|
||||
} else {
|
||||
ret = zfs_share_iscsi(cn->cn_handle);
|
||||
errors +=
|
||||
zfs_share_iscsi(cn->cn_handle);
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((clp->cl_waslegacy || cn->cn_mounted) &&
|
||||
!zfs_is_mounted(cn->cn_handle, NULL) &&
|
||||
/*
|
||||
* Remount if previously mounted or mountpoint was legacy,
|
||||
* or sharenfs or sharesmb property is set.
|
||||
*/
|
||||
sharenfs = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARENFS,
|
||||
shareopts, sizeof (shareopts), NULL, NULL, 0,
|
||||
B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
|
||||
|
||||
sharesmb = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARESMB,
|
||||
shareopts, sizeof (shareopts), NULL, NULL, 0,
|
||||
B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
|
||||
|
||||
if ((cn->cn_mounted || clp->cl_waslegacy || sharenfs ||
|
||||
sharesmb) && !zfs_is_mounted(cn->cn_handle, NULL) &&
|
||||
zfs_mount(cn->cn_handle, NULL, 0) != 0)
|
||||
ret = -1;
|
||||
errors++;
|
||||
|
||||
/*
|
||||
* We always re-share even if the filesystem is currently
|
||||
* shared, so that we can adopt any new options.
|
||||
*/
|
||||
if (cn->cn_shared ||
|
||||
(clp->cl_prop == ZFS_PROP_SHARENFS && clp->cl_waslegacy)) {
|
||||
if (zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARENFS,
|
||||
shareopts, sizeof (shareopts), NULL, NULL, 0,
|
||||
B_FALSE) == 0 && strcmp(shareopts, "off") == 0) {
|
||||
ret = zfs_unshare_nfs(cn->cn_handle, NULL);
|
||||
} else {
|
||||
ret = zfs_share_nfs(cn->cn_handle);
|
||||
}
|
||||
}
|
||||
if (sharenfs)
|
||||
errors += zfs_share_nfs(cn->cn_handle);
|
||||
else if (cn->cn_shared || clp->cl_waslegacy)
|
||||
errors += zfs_unshare_nfs(cn->cn_handle, NULL);
|
||||
if (sharesmb)
|
||||
errors += zfs_share_smb(cn->cn_handle);
|
||||
else if (cn->cn_shared || clp->cl_waslegacy)
|
||||
errors += zfs_unshare_smb(cn->cn_handle, NULL);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
return (errors ? -1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this "dataset" a child of "parent"?
|
||||
*/
|
||||
static boolean_t
|
||||
boolean_t
|
||||
isa_child_of(const char *dataset, const char *parent)
|
||||
{
|
||||
int len;
|
||||
@ -280,21 +348,22 @@ changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a gathered changelist for the 'sharenfs' property, unshare all the
|
||||
* datasets in the list.
|
||||
* Given a gathered changelist for the 'sharenfs' or 'sharesmb' property,
|
||||
* unshare all the datasets in the list.
|
||||
*/
|
||||
int
|
||||
changelist_unshare(prop_changelist_t *clp)
|
||||
changelist_unshare(prop_changelist_t *clp, zfs_share_proto_t *proto)
|
||||
{
|
||||
prop_changenode_t *cn;
|
||||
int ret = 0;
|
||||
|
||||
if (clp->cl_prop != ZFS_PROP_SHARENFS)
|
||||
if (clp->cl_prop != ZFS_PROP_SHARENFS &&
|
||||
clp->cl_prop != ZFS_PROP_SHARESMB)
|
||||
return (0);
|
||||
|
||||
for (cn = uu_list_first(clp->cl_list); cn != NULL;
|
||||
cn = uu_list_next(clp->cl_list, cn)) {
|
||||
if (zfs_unshare_nfs(cn->cn_handle, NULL) != 0)
|
||||
if (zfs_unshare_proto(cn->cn_handle, NULL, proto) != 0)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
@ -316,14 +385,14 @@ changelist_haszonedchild(prop_changelist_t *clp)
|
||||
* Remove a node from a gathered list.
|
||||
*/
|
||||
void
|
||||
changelist_remove(zfs_handle_t *zhp, prop_changelist_t *clp)
|
||||
changelist_remove(prop_changelist_t *clp, const char *name)
|
||||
{
|
||||
prop_changenode_t *cn;
|
||||
|
||||
for (cn = uu_list_first(clp->cl_list); cn != NULL;
|
||||
cn = uu_list_next(clp->cl_list, cn)) {
|
||||
|
||||
if (strcmp(cn->cn_handle->zfs_name, zhp->zfs_name) == 0) {
|
||||
if (strcmp(cn->cn_handle->zfs_name, name) == 0) {
|
||||
uu_list_remove(clp->cl_list, cn);
|
||||
zfs_close(cn->cn_handle);
|
||||
free(cn);
|
||||
@ -363,7 +432,8 @@ change_one(zfs_handle_t *zhp, void *data)
|
||||
char property[ZFS_MAXPROPLEN];
|
||||
char where[64];
|
||||
prop_changenode_t *cn;
|
||||
zfs_source_t sourcetype;
|
||||
zprop_source_t sourcetype;
|
||||
zprop_source_t share_sourcetype;
|
||||
|
||||
/*
|
||||
* We only want to unmount/unshare those filesystems that may inherit
|
||||
@ -383,8 +453,25 @@ change_one(zfs_handle_t *zhp, void *data)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are "watching" sharenfs or sharesmb
|
||||
* then check out the companion property which is tracked
|
||||
* in cl_shareprop
|
||||
*/
|
||||
if (clp->cl_shareprop != ZPROP_INVAL &&
|
||||
zfs_prop_get(zhp, clp->cl_shareprop, property,
|
||||
sizeof (property), &share_sourcetype, where, sizeof (where),
|
||||
B_FALSE) != 0) {
|
||||
zfs_close(zhp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (clp->cl_alldependents || clp->cl_allchildren ||
|
||||
sourcetype == ZFS_SRC_DEFAULT || sourcetype == ZFS_SRC_INHERITED) {
|
||||
sourcetype == ZPROP_SRC_DEFAULT ||
|
||||
sourcetype == ZPROP_SRC_INHERITED ||
|
||||
(clp->cl_shareprop != ZPROP_INVAL &&
|
||||
(share_sourcetype == ZPROP_SRC_DEFAULT ||
|
||||
share_sourcetype == ZPROP_SRC_INHERITED))) {
|
||||
if ((cn = zfs_alloc(zfs_get_handle(zhp),
|
||||
sizeof (prop_changenode_t))) == NULL) {
|
||||
zfs_close(zhp);
|
||||
@ -392,9 +479,11 @@ change_one(zfs_handle_t *zhp, void *data)
|
||||
}
|
||||
|
||||
cn->cn_handle = zhp;
|
||||
cn->cn_mounted = zfs_is_mounted(zhp, NULL);
|
||||
cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) ||
|
||||
zfs_is_mounted(zhp, NULL);
|
||||
cn->cn_shared = zfs_is_shared(zhp);
|
||||
cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
|
||||
cn->cn_needpost = B_TRUE;
|
||||
|
||||
/* Indicate if any child is exported to a local zone. */
|
||||
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
|
||||
@ -467,7 +556,8 @@ compare_mountpoints(const void *a, const void *b, void *unused)
|
||||
* mark whether it was shared beforehand.
|
||||
*/
|
||||
prop_changelist_t *
|
||||
changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
|
||||
changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
|
||||
int mnt_flags)
|
||||
{
|
||||
prop_changelist_t *clp;
|
||||
prop_changenode_t *cn;
|
||||
@ -484,7 +574,8 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
|
||||
* order, regardless of their position in the hierarchy.
|
||||
*/
|
||||
if (prop == ZFS_PROP_NAME || prop == ZFS_PROP_ZONED ||
|
||||
prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS) {
|
||||
prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS ||
|
||||
prop == ZFS_PROP_SHARESMB) {
|
||||
compare = compare_mountpoints;
|
||||
clp->cl_sorted = B_TRUE;
|
||||
}
|
||||
@ -502,7 +593,8 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
|
||||
|
||||
clp->cl_list = uu_list_create(clp->cl_pool, NULL,
|
||||
clp->cl_sorted ? UU_LIST_SORTED : 0);
|
||||
clp->cl_flags = flags;
|
||||
clp->cl_gflags = gather_flags;
|
||||
clp->cl_mflags = mnt_flags;
|
||||
|
||||
if (clp->cl_list == NULL) {
|
||||
assert(uu_error() == UU_ERROR_NO_MEMORY);
|
||||
@ -529,6 +621,8 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
|
||||
clp->cl_prop = ZFS_PROP_MOUNTPOINT;
|
||||
} else if (prop == ZFS_PROP_VOLSIZE) {
|
||||
clp->cl_prop = ZFS_PROP_MOUNTPOINT;
|
||||
} else if (prop == ZFS_PROP_VERSION) {
|
||||
clp->cl_prop = ZFS_PROP_MOUNTPOINT;
|
||||
} else {
|
||||
clp->cl_prop = prop;
|
||||
}
|
||||
@ -536,9 +630,19 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
|
||||
|
||||
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
|
||||
clp->cl_prop != ZFS_PROP_SHARENFS &&
|
||||
clp->cl_prop != ZFS_PROP_SHARESMB &&
|
||||
clp->cl_prop != ZFS_PROP_SHAREISCSI)
|
||||
return (clp);
|
||||
|
||||
/*
|
||||
* If watching SHARENFS or SHARESMB then
|
||||
* also watch its companion property.
|
||||
*/
|
||||
if (clp->cl_prop == ZFS_PROP_SHARENFS)
|
||||
clp->cl_shareprop = ZFS_PROP_SHARESMB;
|
||||
else if (clp->cl_prop == ZFS_PROP_SHARESMB)
|
||||
clp->cl_shareprop = ZFS_PROP_SHARENFS;
|
||||
|
||||
if (clp->cl_alldependents) {
|
||||
if (zfs_iter_dependents(zhp, B_TRUE, change_one, clp) != 0) {
|
||||
changelist_free(clp);
|
||||
@ -554,7 +658,7 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
|
||||
* and can't tell the difference.
|
||||
*/
|
||||
if ((temp = zfs_open(zhp->zfs_hdl, zfs_get_name(zhp),
|
||||
ZFS_TYPE_ANY)) == NULL) {
|
||||
ZFS_TYPE_DATASET)) == NULL) {
|
||||
changelist_free(clp);
|
||||
return (NULL);
|
||||
}
|
||||
@ -571,9 +675,11 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
|
||||
}
|
||||
|
||||
cn->cn_handle = temp;
|
||||
cn->cn_mounted = zfs_is_mounted(temp, NULL);
|
||||
cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) ||
|
||||
zfs_is_mounted(temp, NULL);
|
||||
cn->cn_shared = zfs_is_shared(temp);
|
||||
cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
|
||||
cn->cn_needpost = B_TRUE;
|
||||
|
||||
uu_list_node_init(cn, &cn->cn_listnode, clp->cl_pool);
|
||||
if (clp->cl_sorted) {
|
||||
@ -586,14 +692,22 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
|
||||
}
|
||||
|
||||
/*
|
||||
* If the property was previously 'legacy' or 'none', record this fact,
|
||||
* as the behavior of changelist_postfix() will be different.
|
||||
* If the mountpoint property was previously 'legacy', or 'none',
|
||||
* record it as the behavior of changelist_postfix() will be different.
|
||||
*/
|
||||
if (zfs_prop_get(zhp, prop, property, sizeof (property),
|
||||
if ((clp->cl_prop == ZFS_PROP_MOUNTPOINT) &&
|
||||
(zfs_prop_get(zhp, prop, property, sizeof (property),
|
||||
NULL, NULL, 0, B_FALSE) == 0 &&
|
||||
(strcmp(property, "legacy") == 0 || strcmp(property, "none") == 0 ||
|
||||
strcmp(property, "off") == 0))
|
||||
clp->cl_waslegacy = B_TRUE;
|
||||
(strcmp(property, "legacy") == 0 ||
|
||||
strcmp(property, "none") == 0))) {
|
||||
/*
|
||||
* do not automatically mount ex-legacy datasets if
|
||||
* we specifically set canmount to noauto
|
||||
*/
|
||||
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) !=
|
||||
ZFS_CANMOUNT_NOAUTO)
|
||||
clp->cl_waslegacy = B_TRUE;
|
||||
}
|
||||
|
||||
return (clp);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -126,6 +126,8 @@ typedef struct zfs_graph {
|
||||
zfs_vertex_t **zg_hash;
|
||||
size_t zg_size;
|
||||
size_t zg_nvertex;
|
||||
const char *zg_root;
|
||||
int zg_clone_count;
|
||||
} zfs_graph_t;
|
||||
|
||||
/*
|
||||
@ -255,7 +257,7 @@ zfs_vertex_sort_edges(zfs_vertex_t *zvp)
|
||||
* datasets in the pool.
|
||||
*/
|
||||
static zfs_graph_t *
|
||||
zfs_graph_create(libzfs_handle_t *hdl, size_t size)
|
||||
zfs_graph_create(libzfs_handle_t *hdl, const char *dataset, size_t size)
|
||||
{
|
||||
zfs_graph_t *zgp = zfs_alloc(hdl, sizeof (zfs_graph_t));
|
||||
|
||||
@ -269,6 +271,9 @@ zfs_graph_create(libzfs_handle_t *hdl, size_t size)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
zgp->zg_root = dataset;
|
||||
zgp->zg_clone_count = 0;
|
||||
|
||||
return (zgp);
|
||||
}
|
||||
|
||||
@ -367,17 +372,16 @@ zfs_graph_add(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *source,
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over all children of the given dataset, adding any vertices as
|
||||
* necessary. Returns 0 if no cloned snapshots were seen, -1 if there was an
|
||||
* error, or 1 otherwise. This is a simple recursive algorithm - the ZFS
|
||||
* namespace typically is very flat. We manually invoke the necessary ioctl()
|
||||
* calls to avoid the overhead and additional semantics of zfs_open().
|
||||
* Iterate over all children of the given dataset, adding any vertices
|
||||
* as necessary. Returns -1 if there was an error, or 0 otherwise.
|
||||
* This is a simple recursive algorithm - the ZFS namespace typically
|
||||
* is very flat. We manually invoke the necessary ioctl() calls to
|
||||
* avoid the overhead and additional semantics of zfs_open().
|
||||
*/
|
||||
static int
|
||||
iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
|
||||
{
|
||||
zfs_cmd_t zc = { 0 };
|
||||
int ret = 0, err;
|
||||
zfs_vertex_t *zvp;
|
||||
|
||||
/*
|
||||
@ -390,18 +394,8 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* We check the clone parent here instead of within the loop, so that if
|
||||
* the root dataset has been promoted from a clone, we find its parent
|
||||
* appropriately.
|
||||
* Iterate over all children
|
||||
*/
|
||||
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
|
||||
if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0 &&
|
||||
zc.zc_objset_stats.dds_clone_of[0] != '\0') {
|
||||
if (zfs_graph_add(hdl, zgp, zc.zc_objset_stats.dds_clone_of,
|
||||
zc.zc_name, zc.zc_objset_stats.dds_creation_txg) != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for ((void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
|
||||
ioctl(hdl->libzfs_fd, ZFS_IOC_DATASET_LIST_NEXT, &zc) == 0;
|
||||
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name))) {
|
||||
@ -417,9 +411,23 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
|
||||
* dataset and clone statistics. If this fails, the dataset has
|
||||
* since been removed, and we're pretty much screwed anyway.
|
||||
*/
|
||||
zc.zc_objset_stats.dds_origin[0] = '\0';
|
||||
if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0)
|
||||
continue;
|
||||
|
||||
if (zc.zc_objset_stats.dds_origin[0] != '\0') {
|
||||
if (zfs_graph_add(hdl, zgp,
|
||||
zc.zc_objset_stats.dds_origin, zc.zc_name,
|
||||
zc.zc_objset_stats.dds_creation_txg) != 0)
|
||||
return (-1);
|
||||
/*
|
||||
* Count origins only if they are contained in the graph
|
||||
*/
|
||||
if (isa_child_of(zc.zc_objset_stats.dds_origin,
|
||||
zgp->zg_root))
|
||||
zgp->zg_clone_count--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an edge between the parent and the child.
|
||||
*/
|
||||
@ -428,19 +436,10 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Iterate over all children
|
||||
* Recursively visit child
|
||||
*/
|
||||
err = iterate_children(hdl, zgp, zc.zc_name);
|
||||
if (err == -1)
|
||||
if (iterate_children(hdl, zgp, zc.zc_name))
|
||||
return (-1);
|
||||
else if (err == 1)
|
||||
ret = 1;
|
||||
|
||||
/*
|
||||
* Indicate if we found a dataset with a non-zero clone count.
|
||||
*/
|
||||
if (zc.zc_objset_stats.dds_num_clones != 0)
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -467,67 +466,84 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
|
||||
zc.zc_objset_stats.dds_creation_txg) != 0)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Indicate if we found a dataset with a non-zero clone count.
|
||||
*/
|
||||
if (zc.zc_objset_stats.dds_num_clones != 0)
|
||||
ret = 1;
|
||||
zgp->zg_clone_count += zc.zc_objset_stats.dds_num_clones;
|
||||
}
|
||||
|
||||
zvp->zv_visited = VISIT_SEEN;
|
||||
|
||||
return (ret);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a complete graph of all necessary vertices. First, we iterate over
|
||||
* only our object's children. If we don't find any cloned snapshots, then we
|
||||
* simple return that. Otherwise, we have to start at the pool root and iterate
|
||||
* over all datasets.
|
||||
* Returns false if there are no snapshots with dependent clones in this
|
||||
* subtree or if all of those clones are also in this subtree. Returns
|
||||
* true if there is an error or there are external dependents.
|
||||
*/
|
||||
static boolean_t
|
||||
external_dependents(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
|
||||
{
|
||||
zfs_cmd_t zc = { 0 };
|
||||
|
||||
/*
|
||||
* Check whether this dataset is a clone or has clones since
|
||||
* iterate_children() only checks the children.
|
||||
*/
|
||||
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
|
||||
if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0)
|
||||
return (B_TRUE);
|
||||
|
||||
if (zc.zc_objset_stats.dds_origin[0] != '\0') {
|
||||
if (zfs_graph_add(hdl, zgp,
|
||||
zc.zc_objset_stats.dds_origin, zc.zc_name,
|
||||
zc.zc_objset_stats.dds_creation_txg) != 0)
|
||||
return (B_TRUE);
|
||||
if (isa_child_of(zc.zc_objset_stats.dds_origin, dataset))
|
||||
zgp->zg_clone_count--;
|
||||
}
|
||||
|
||||
if ((zc.zc_objset_stats.dds_num_clones) ||
|
||||
iterate_children(hdl, zgp, dataset))
|
||||
return (B_TRUE);
|
||||
|
||||
return (zgp->zg_clone_count != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a complete graph of all necessary vertices. First, iterate over
|
||||
* only our object's children. If no cloned snapshots are found, or all of
|
||||
* the cloned snapshots are in this subtree then return a graph of the subtree.
|
||||
* Otherwise, start at the root of the pool and iterate over all datasets.
|
||||
*/
|
||||
static zfs_graph_t *
|
||||
construct_graph(libzfs_handle_t *hdl, const char *dataset)
|
||||
{
|
||||
zfs_graph_t *zgp = zfs_graph_create(hdl, ZFS_GRAPH_SIZE);
|
||||
zfs_cmd_t zc = { 0 };
|
||||
zfs_graph_t *zgp = zfs_graph_create(hdl, dataset, ZFS_GRAPH_SIZE);
|
||||
int ret = 0;
|
||||
|
||||
if (zgp == NULL)
|
||||
return (zgp);
|
||||
|
||||
/*
|
||||
* We need to explicitly check whether this dataset has clones or not,
|
||||
* since iterate_children() only checks the children.
|
||||
*/
|
||||
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
|
||||
(void) ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc);
|
||||
|
||||
if (zc.zc_objset_stats.dds_num_clones != 0 ||
|
||||
(ret = iterate_children(hdl, zgp, dataset)) != 0) {
|
||||
if ((strchr(dataset, '/') == NULL) ||
|
||||
(external_dependents(hdl, zgp, dataset))) {
|
||||
/*
|
||||
* Determine pool name and try again.
|
||||
*/
|
||||
char *pool, *slash;
|
||||
int len = strcspn(dataset, "/@") + 1;
|
||||
char *pool = zfs_alloc(hdl, len);
|
||||
|
||||
if ((slash = strchr(dataset, '/')) != NULL ||
|
||||
(slash = strchr(dataset, '@')) != NULL) {
|
||||
pool = zfs_alloc(hdl, slash - dataset + 1);
|
||||
if (pool == NULL) {
|
||||
zfs_graph_destroy(zgp);
|
||||
return (NULL);
|
||||
}
|
||||
(void) strncpy(pool, dataset, slash - dataset);
|
||||
pool[slash - dataset] = '\0';
|
||||
|
||||
if (iterate_children(hdl, zgp, pool) == -1 ||
|
||||
zfs_graph_add(hdl, zgp, pool, NULL, 0) != 0) {
|
||||
free(pool);
|
||||
zfs_graph_destroy(zgp);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
free(pool);
|
||||
if (pool == NULL) {
|
||||
zfs_graph_destroy(zgp);
|
||||
return (NULL);
|
||||
}
|
||||
(void) strlcpy(pool, dataset, len);
|
||||
|
||||
if (iterate_children(hdl, zgp, pool) == -1 ||
|
||||
zfs_graph_add(hdl, zgp, pool, NULL, 0) != 0) {
|
||||
free(pool);
|
||||
zfs_graph_destroy(zgp);
|
||||
return (NULL);
|
||||
}
|
||||
free(pool);
|
||||
}
|
||||
|
||||
if (ret == -1 || zfs_graph_add(hdl, zgp, dataset, NULL, 0) != 0) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
* CDDL HEADER SART
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
@ -20,21 +20,21 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _LIBFS_IMPL_H
|
||||
#define _LIBFS_IMPL_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <sys/dmu.h>
|
||||
#include <sys/fs/zfs.h>
|
||||
#include <sys/zfs_ioctl.h>
|
||||
#include <sys/zfs_acl.h>
|
||||
#include <sys/spa.h>
|
||||
#include <sys/nvpair.h>
|
||||
|
||||
#include <libshare.h>
|
||||
#include <libuutil.h>
|
||||
#include <libzfs.h>
|
||||
|
||||
@ -42,22 +42,33 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef VERIFY
|
||||
#undef VERIFY
|
||||
#endif
|
||||
#define VERIFY verify
|
||||
|
||||
struct libzfs_handle {
|
||||
int libzfs_error;
|
||||
int libzfs_fd;
|
||||
FILE *libzfs_mnttab;
|
||||
FILE *libzfs_sharetab;
|
||||
zpool_handle_t *libzfs_pool_handles;
|
||||
uu_avl_pool_t *libzfs_ns_avlpool;
|
||||
uu_avl_t *libzfs_ns_avl;
|
||||
uint64_t libzfs_ns_gen;
|
||||
int libzfs_desc_active;
|
||||
char libzfs_action[1024];
|
||||
char libzfs_desc[1024];
|
||||
char *libzfs_log_str;
|
||||
int libzfs_printerr;
|
||||
void *libzfs_sharehdl; /* libshare handle */
|
||||
uint_t libzfs_shareflags;
|
||||
};
|
||||
#define ZFSSHARE_MISS 0x01 /* Didn't find entry in cache */
|
||||
|
||||
struct zfs_handle {
|
||||
libzfs_handle_t *zfs_hdl;
|
||||
zpool_handle_t *zpool_hdl;
|
||||
char zfs_name[ZFS_MAXNAMELEN];
|
||||
zfs_type_t zfs_type; /* type including snapshot */
|
||||
zfs_type_t zfs_head_type; /* type excluding snapshot */
|
||||
@ -66,7 +77,6 @@ struct zfs_handle {
|
||||
nvlist_t *zfs_user_props;
|
||||
boolean_t zfs_mntcheck;
|
||||
char *zfs_mntopts;
|
||||
char zfs_root[MAXPATHLEN];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -77,14 +87,33 @@ struct zfs_handle {
|
||||
|
||||
struct zpool_handle {
|
||||
libzfs_handle_t *zpool_hdl;
|
||||
zpool_handle_t *zpool_next;
|
||||
char zpool_name[ZPOOL_MAXNAMELEN];
|
||||
int zpool_state;
|
||||
size_t zpool_config_size;
|
||||
nvlist_t *zpool_config;
|
||||
nvlist_t *zpool_old_config;
|
||||
nvlist_t *zpool_props;
|
||||
diskaddr_t zpool_start_block;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
PROTO_NFS = 0,
|
||||
PROTO_SMB = 1,
|
||||
PROTO_END = 2
|
||||
} zfs_share_proto_t;
|
||||
|
||||
/*
|
||||
* The following can be used as a bitmask and any new values
|
||||
* added must preserve that capability.
|
||||
*/
|
||||
typedef enum {
|
||||
SHARED_NOT_SHARED = 0x0,
|
||||
SHARED_ISCSI = 0x1,
|
||||
SHARED_NFS = 0x2,
|
||||
SHARED_SMB = 0x4
|
||||
} zfs_share_type_t;
|
||||
|
||||
int zfs_error(libzfs_handle_t *, int, const char *);
|
||||
int zfs_error_fmt(libzfs_handle_t *, int, const char *, ...);
|
||||
void zfs_error_aux(libzfs_handle_t *, const char *, ...);
|
||||
@ -101,20 +130,24 @@ int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...);
|
||||
int get_dependents(libzfs_handle_t *, boolean_t, const char *, char ***,
|
||||
size_t *);
|
||||
|
||||
int zfs_expand_proplist_common(libzfs_handle_t *, zfs_proplist_t **,
|
||||
zfs_type_t);
|
||||
int zfs_get_proplist_common(libzfs_handle_t *, char *, zfs_proplist_t **,
|
||||
zfs_type_t);
|
||||
zfs_prop_t zfs_prop_iter_common(zfs_prop_f, void *, zfs_type_t, boolean_t);
|
||||
zfs_prop_t zfs_name_to_prop_common(const char *, zfs_type_t);
|
||||
|
||||
nvlist_t *zfs_validate_properties(libzfs_handle_t *, zfs_type_t, char *,
|
||||
nvlist_t *, uint64_t, zfs_handle_t *zhp, const char *errbuf);
|
||||
int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t,
|
||||
nvlist_t *, char **, uint64_t *, const char *);
|
||||
int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp,
|
||||
zfs_type_t type);
|
||||
|
||||
/*
|
||||
* Use this changelist_gather() flag to force attempting mounts
|
||||
* on each change node regardless of whether or not it is currently
|
||||
* mounted.
|
||||
*/
|
||||
#define CL_GATHER_MOUNT_ALWAYS 1
|
||||
|
||||
typedef struct prop_changelist prop_changelist_t;
|
||||
|
||||
int zcmd_alloc_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, size_t);
|
||||
int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *, size_t *);
|
||||
int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
|
||||
int zcmd_write_conf_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
|
||||
int zcmd_expand_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *);
|
||||
int zcmd_read_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t **);
|
||||
void zcmd_free_nvlists(zfs_cmd_t *);
|
||||
@ -122,13 +155,15 @@ void zcmd_free_nvlists(zfs_cmd_t *);
|
||||
int changelist_prefix(prop_changelist_t *);
|
||||
int changelist_postfix(prop_changelist_t *);
|
||||
void changelist_rename(prop_changelist_t *, const char *, const char *);
|
||||
void changelist_remove(zfs_handle_t *, prop_changelist_t *);
|
||||
void changelist_remove(prop_changelist_t *, const char *);
|
||||
void changelist_free(prop_changelist_t *);
|
||||
prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int);
|
||||
int changelist_unshare(prop_changelist_t *);
|
||||
prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int, int);
|
||||
int changelist_unshare(prop_changelist_t *, zfs_share_proto_t *);
|
||||
int changelist_haszonedchild(prop_changelist_t *);
|
||||
|
||||
void remove_mountpoint(zfs_handle_t *);
|
||||
int create_parents(libzfs_handle_t *, char *, int);
|
||||
boolean_t isa_child_of(const char *dataset, const char *parent);
|
||||
|
||||
zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *);
|
||||
|
||||
@ -137,10 +172,23 @@ int zpool_open_silent(libzfs_handle_t *, const char *, zpool_handle_t **);
|
||||
int zvol_create_link(libzfs_handle_t *, const char *);
|
||||
int zvol_remove_link(libzfs_handle_t *, const char *);
|
||||
int zpool_iter_zvol(zpool_handle_t *, int (*)(const char *, void *), void *);
|
||||
boolean_t zpool_name_valid(libzfs_handle_t *, boolean_t, const char *);
|
||||
|
||||
void namespace_clear(libzfs_handle_t *);
|
||||
|
||||
/*
|
||||
* libshare (sharemgr) interfaces used internally.
|
||||
*/
|
||||
|
||||
extern int zfs_init_libshare(libzfs_handle_t *, int);
|
||||
extern void zfs_uninit_libshare(libzfs_handle_t *);
|
||||
extern int zfs_parse_options(char *, zfs_share_proto_t);
|
||||
|
||||
extern int zfs_unshare_proto(zfs_handle_t *zhp,
|
||||
const char *, zfs_share_proto_t *);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
/*
|
||||
* This is FreeBSD version of ioctl, because Solaris' ioctl() updates
|
||||
* zc_nvlist_dst_size even if an error is returned, on FreeBSD if an
|
||||
|
@ -19,7 +19,7 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -213,11 +213,13 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
|
||||
name_entry_t *ne;
|
||||
|
||||
/*
|
||||
* If this is a hot spare not currently in use, add it to the list of
|
||||
* names to translate, but don't do anything else.
|
||||
* If this is a hot spare not currently in use or level 2 cache
|
||||
* device, add it to the list of names to translate, but don't do
|
||||
* anything else.
|
||||
*/
|
||||
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
|
||||
&state) == 0 && state == POOL_STATE_SPARE &&
|
||||
&state) == 0 &&
|
||||
(state == POOL_STATE_SPARE || state == POOL_STATE_L2CACHE) &&
|
||||
nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid) == 0) {
|
||||
if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL)
|
||||
return (-1);
|
||||
@ -361,6 +363,46 @@ pool_active(libzfs_handle_t *hdl, const char *name, uint64_t guid,
|
||||
return (0);
|
||||
}
|
||||
|
||||
static nvlist_t *
|
||||
refresh_config(libzfs_handle_t *hdl, nvlist_t *config)
|
||||
{
|
||||
nvlist_t *nvl;
|
||||
zfs_cmd_t zc = { 0 };
|
||||
int err;
|
||||
|
||||
if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (zcmd_alloc_dst_nvlist(hdl, &zc,
|
||||
zc.zc_nvlist_conf_size * 2) != 0) {
|
||||
zcmd_free_nvlists(&zc);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
while ((err = ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_TRYIMPORT,
|
||||
&zc)) != 0 && errno == ENOMEM) {
|
||||
if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
|
||||
zcmd_free_nvlists(&zc);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (err) {
|
||||
(void) zpool_standard_error(hdl, errno,
|
||||
dgettext(TEXT_DOMAIN, "cannot discover pools"));
|
||||
zcmd_free_nvlists(&zc);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (zcmd_read_dst_nvlist(hdl, &zc, &nvl) != 0) {
|
||||
zcmd_free_nvlists(&zc);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
zcmd_free_nvlists(&zc);
|
||||
return (nvl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert our list of pools into the definitive set of configurations. We
|
||||
* start by picking the best config for each toplevel vdev. Once that's done,
|
||||
@ -369,26 +411,25 @@ pool_active(libzfs_handle_t *hdl, const char *name, uint64_t guid,
|
||||
* return to the user.
|
||||
*/
|
||||
static nvlist_t *
|
||||
get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
||||
get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
|
||||
{
|
||||
pool_entry_t *pe;
|
||||
vdev_entry_t *ve;
|
||||
config_entry_t *ce;
|
||||
nvlist_t *ret = NULL, *config = NULL, *tmp, *nvtop, *nvroot;
|
||||
nvlist_t **spares;
|
||||
uint_t i, nspares;
|
||||
nvlist_t **spares, **l2cache;
|
||||
uint_t i, nspares, nl2cache;
|
||||
boolean_t config_seen;
|
||||
uint64_t best_txg;
|
||||
char *name, *hostname;
|
||||
zfs_cmd_t zc = { 0 };
|
||||
uint64_t version, guid;
|
||||
size_t len;
|
||||
int err;
|
||||
uint_t children = 0;
|
||||
nvlist_t **child = NULL;
|
||||
uint_t c;
|
||||
boolean_t isactive;
|
||||
uint64_t hostid;
|
||||
nvlist_t *nvl;
|
||||
boolean_t found_one = B_FALSE;
|
||||
|
||||
if (nvlist_alloc(&ret, 0, 0) != 0)
|
||||
goto nomem;
|
||||
@ -570,6 +611,13 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
||||
}
|
||||
nvlist_free(nvroot);
|
||||
|
||||
/*
|
||||
* zdb uses this path to report on active pools that were
|
||||
* imported or created using -R.
|
||||
*/
|
||||
if (active_ok)
|
||||
goto add_pool;
|
||||
|
||||
/*
|
||||
* Determine if this pool is currently active, in which case we
|
||||
* can't actually import it.
|
||||
@ -588,41 +636,11 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to do the import in order to get vdev state.
|
||||
*/
|
||||
if (zcmd_write_src_nvlist(hdl, &zc, config, &len) != 0)
|
||||
if ((nvl = refresh_config(hdl, config)) == NULL)
|
||||
goto error;
|
||||
|
||||
nvlist_free(config);
|
||||
config = NULL;
|
||||
|
||||
if (zcmd_alloc_dst_nvlist(hdl, &zc, len * 2) != 0) {
|
||||
zcmd_free_nvlists(&zc);
|
||||
goto error;
|
||||
}
|
||||
|
||||
while ((err = ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_TRYIMPORT,
|
||||
&zc)) != 0 && errno == ENOMEM) {
|
||||
if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
|
||||
zcmd_free_nvlists(&zc);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (err) {
|
||||
(void) zpool_standard_error(hdl, errno,
|
||||
dgettext(TEXT_DOMAIN, "cannot discover pools"));
|
||||
zcmd_free_nvlists(&zc);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (zcmd_read_dst_nvlist(hdl, &zc, &config) != 0) {
|
||||
zcmd_free_nvlists(&zc);
|
||||
goto error;
|
||||
}
|
||||
|
||||
zcmd_free_nvlists(&zc);
|
||||
config = nvl;
|
||||
|
||||
/*
|
||||
* Go through and update the paths for spares, now that we have
|
||||
@ -638,6 +656,17 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the paths for l2cache devices.
|
||||
*/
|
||||
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
|
||||
&l2cache, &nl2cache) == 0) {
|
||||
for (i = 0; i < nl2cache; i++) {
|
||||
if (fix_paths(l2cache[i], pl->names) != 0)
|
||||
goto nomem;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the original information read from the actual label.
|
||||
*/
|
||||
@ -652,6 +681,7 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
||||
hostname) == 0);
|
||||
}
|
||||
|
||||
add_pool:
|
||||
/*
|
||||
* Add this pool to the list of configs.
|
||||
*/
|
||||
@ -660,10 +690,16 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
||||
if (nvlist_add_nvlist(ret, name, config) != 0)
|
||||
goto nomem;
|
||||
|
||||
found_one = B_TRUE;
|
||||
nvlist_free(config);
|
||||
config = NULL;
|
||||
}
|
||||
|
||||
if (!found_one) {
|
||||
nvlist_free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
|
||||
nomem:
|
||||
@ -682,8 +718,9 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
||||
* Return the offset of the given label.
|
||||
*/
|
||||
static uint64_t
|
||||
label_offset(size_t size, int l)
|
||||
label_offset(uint64_t size, int l)
|
||||
{
|
||||
ASSERT(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t) == 0);
|
||||
return (l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
|
||||
0 : size - VDEV_LABELS * sizeof (vdev_label_t)));
|
||||
}
|
||||
@ -698,19 +735,20 @@ zpool_read_label(int fd, nvlist_t **config)
|
||||
struct stat64 statbuf;
|
||||
int l;
|
||||
vdev_label_t *label;
|
||||
uint64_t state, txg;
|
||||
uint64_t state, txg, size;
|
||||
|
||||
*config = NULL;
|
||||
|
||||
if (fstat64(fd, &statbuf) == -1)
|
||||
return (0);
|
||||
size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
|
||||
|
||||
if ((label = malloc(sizeof (vdev_label_t))) == NULL)
|
||||
return (-1);
|
||||
|
||||
for (l = 0; l < VDEV_LABELS; l++) {
|
||||
if (pread(fd, label, sizeof (vdev_label_t),
|
||||
label_offset(statbuf.st_size, l)) != sizeof (vdev_label_t))
|
||||
if (pread64(fd, label, sizeof (vdev_label_t),
|
||||
label_offset(size, l)) != sizeof (vdev_label_t))
|
||||
continue;
|
||||
|
||||
if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
|
||||
@ -718,12 +756,12 @@ zpool_read_label(int fd, nvlist_t **config)
|
||||
continue;
|
||||
|
||||
if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
|
||||
&state) != 0 || state > POOL_STATE_SPARE) {
|
||||
&state) != 0 || state > POOL_STATE_L2CACHE) {
|
||||
nvlist_free(*config);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state != POOL_STATE_SPARE &&
|
||||
if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
|
||||
(nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
|
||||
&txg) != 0 || txg == 0)) {
|
||||
nvlist_free(*config);
|
||||
@ -739,31 +777,20 @@ zpool_read_label(int fd, nvlist_t **config)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a list of directories to search, find all pools stored on disk. This
|
||||
* includes partial pools which are not available to import. If no args are
|
||||
* given (argc is 0), then the default directory (/dev) is searched.
|
||||
*/
|
||||
nvlist_t *
|
||||
zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
|
||||
static int
|
||||
geom_find_import(libzfs_handle_t *hdl, pool_list_t *pools)
|
||||
{
|
||||
int i;
|
||||
char path[MAXPATHLEN];
|
||||
nvlist_t *ret = NULL, *config;
|
||||
int fd;
|
||||
pool_list_t pools = { 0 };
|
||||
pool_entry_t *pe, *penext;
|
||||
vdev_entry_t *ve, *venext;
|
||||
config_entry_t *ce, *cenext;
|
||||
name_entry_t *ne, *nenext;
|
||||
struct gmesh mesh;
|
||||
struct gclass *mp;
|
||||
struct ggeom *gp;
|
||||
struct gprovider *pp;
|
||||
nvlist_t *config;
|
||||
int fd, ret = 0;
|
||||
|
||||
/*
|
||||
* Go through and read the label configuration information from every
|
||||
* possible device, organizing the information according to pool GUID
|
||||
* GEOM provider, organizing the information according to pool GUID
|
||||
* and toplevel GUID.
|
||||
*/
|
||||
|
||||
@ -773,32 +800,183 @@ zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
|
||||
LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
|
||||
LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
|
||||
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
|
||||
if ((fd = g_open(pp->lg_name, 0)) < 0)
|
||||
continue;
|
||||
|
||||
(void) snprintf(path, sizeof (path), "%s%s",
|
||||
_PATH_DEV, pp->lg_name);
|
||||
|
||||
if ((fd = open64(path, O_RDONLY)) < 0)
|
||||
continue;
|
||||
|
||||
if ((zpool_read_label(fd, &config)) != 0) {
|
||||
(void) g_close(fd);
|
||||
(void) no_memory(hdl);
|
||||
goto error;
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
(void) g_close(fd);
|
||||
|
||||
if (config == NULL)
|
||||
continue;
|
||||
|
||||
if (add_config(hdl, pools, path, config) != 0) {
|
||||
ret = -1;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
error:
|
||||
geom_deletetree(&mesh);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a list of directories to search, find all pools stored on disk. This
|
||||
* includes partial pools which are not available to import. If no args are
|
||||
* given (argc is 0), then the default directory (/dev/dsk) is searched.
|
||||
* poolname or guid (but not both) are provided by the caller when trying
|
||||
* to import a specific pool.
|
||||
*/
|
||||
static nvlist_t *
|
||||
zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv,
|
||||
boolean_t active_ok, char *poolname, uint64_t guid)
|
||||
{
|
||||
int i;
|
||||
DIR *dirp = NULL;
|
||||
struct dirent64 *dp;
|
||||
char path[MAXPATHLEN];
|
||||
char *end;
|
||||
size_t pathleft;
|
||||
struct stat64 statbuf;
|
||||
nvlist_t *ret = NULL, *config;
|
||||
static char *default_dir = "/dev/dsk";
|
||||
int fd;
|
||||
pool_list_t pools = { 0 };
|
||||
pool_entry_t *pe, *penext;
|
||||
vdev_entry_t *ve, *venext;
|
||||
config_entry_t *ce, *cenext;
|
||||
name_entry_t *ne, *nenext;
|
||||
|
||||
verify(poolname == NULL || guid == 0);
|
||||
|
||||
if (argc == 0) {
|
||||
argc = 1;
|
||||
argv = &default_dir;
|
||||
}
|
||||
|
||||
/*
|
||||
* Go through and read the label configuration information from every
|
||||
* possible device, organizing the information according to pool GUID
|
||||
* and toplevel GUID.
|
||||
*/
|
||||
for (i = 0; i < argc; i++) {
|
||||
char *rdsk;
|
||||
int dfd;
|
||||
|
||||
/* use realpath to normalize the path */
|
||||
if (realpath(argv[i], path) == 0) {
|
||||
(void) zfs_error_fmt(hdl, EZFS_BADPATH,
|
||||
dgettext(TEXT_DOMAIN, "cannot open '%s'"),
|
||||
argv[i]);
|
||||
goto error;
|
||||
}
|
||||
end = &path[strlen(path)];
|
||||
*end++ = '/';
|
||||
*end = 0;
|
||||
pathleft = &path[sizeof (path)] - end;
|
||||
|
||||
if (strcmp(argv[i], default_dir) == 0) {
|
||||
geom_find_import(hdl, &pools);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Using raw devices instead of block devices when we're
|
||||
* reading the labels skips a bunch of slow operations during
|
||||
* close(2) processing, so we replace /dev/dsk with /dev/rdsk.
|
||||
*/
|
||||
if (strcmp(path, "/dev/dsk/") == 0)
|
||||
rdsk = "/dev/rdsk/";
|
||||
else
|
||||
rdsk = path;
|
||||
|
||||
if ((dirp = opendir(rdsk)) == NULL) {
|
||||
zfs_error_aux(hdl, strerror(errno));
|
||||
(void) zfs_error_fmt(hdl, EZFS_BADPATH,
|
||||
dgettext(TEXT_DOMAIN, "cannot open '%s'"),
|
||||
rdsk);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is not MT-safe, but we have no MT consumers of libzfs
|
||||
*/
|
||||
while ((dp = readdir64(dirp)) != NULL) {
|
||||
const char *name = dp->d_name;
|
||||
if (name[0] == '.' &&
|
||||
(name[1] == 0 || (name[1] == '.' && name[2] == 0)))
|
||||
continue;
|
||||
|
||||
(void) snprintf(path, sizeof (path), "%s/%s", rdsk,
|
||||
dp->d_name);
|
||||
|
||||
if ((fd = open64(path, O_RDONLY)) < 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Ignore failed stats. We only want regular
|
||||
* files, character devs and block devs.
|
||||
*/
|
||||
if (fstat64(fd, &statbuf) != 0 ||
|
||||
(!S_ISREG(statbuf.st_mode) &&
|
||||
!S_ISCHR(statbuf.st_mode) &&
|
||||
!S_ISBLK(statbuf.st_mode))) {
|
||||
(void) close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((zpool_read_label(fd, &config)) != 0) {
|
||||
(void) close(fd);
|
||||
(void) no_memory(hdl);
|
||||
goto error;
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
|
||||
if (config != NULL) {
|
||||
boolean_t matched = B_TRUE;
|
||||
|
||||
if (poolname != NULL) {
|
||||
char *pname;
|
||||
|
||||
matched = nvlist_lookup_string(config,
|
||||
ZPOOL_CONFIG_POOL_NAME,
|
||||
&pname) == 0 &&
|
||||
strcmp(poolname, pname) == 0;
|
||||
} else if (guid != 0) {
|
||||
uint64_t this_guid;
|
||||
|
||||
matched = nvlist_lookup_uint64(config,
|
||||
ZPOOL_CONFIG_POOL_GUID,
|
||||
&this_guid) == 0 &&
|
||||
guid == this_guid;
|
||||
}
|
||||
if (!matched) {
|
||||
nvlist_free(config);
|
||||
config = NULL;
|
||||
continue;
|
||||
}
|
||||
/* use the non-raw path for the config */
|
||||
(void) strlcpy(end, name, pathleft);
|
||||
if (add_config(hdl, &pools, path, config) != 0)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
(void) closedir(dirp);
|
||||
dirp = NULL;
|
||||
}
|
||||
|
||||
geom_deletetree(&mesh);
|
||||
|
||||
ret = get_configs(hdl, &pools);
|
||||
ret = get_configs(hdl, &pools, active_ok);
|
||||
|
||||
error:
|
||||
for (pe = pools.pools; pe != NULL; pe = penext) {
|
||||
@ -823,9 +1001,158 @@ zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
|
||||
free(ne);
|
||||
}
|
||||
|
||||
if (dirp)
|
||||
(void) closedir(dirp);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
nvlist_t *
|
||||
zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
|
||||
{
|
||||
return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, 0));
|
||||
}
|
||||
|
||||
nvlist_t *
|
||||
zpool_find_import_byname(libzfs_handle_t *hdl, int argc, char **argv,
|
||||
char *pool)
|
||||
{
|
||||
return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, pool, 0));
|
||||
}
|
||||
|
||||
nvlist_t *
|
||||
zpool_find_import_byguid(libzfs_handle_t *hdl, int argc, char **argv,
|
||||
uint64_t guid)
|
||||
{
|
||||
return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, guid));
|
||||
}
|
||||
|
||||
nvlist_t *
|
||||
zpool_find_import_activeok(libzfs_handle_t *hdl, int argc, char **argv)
|
||||
{
|
||||
return (zpool_find_import_impl(hdl, argc, argv, B_TRUE, NULL, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a cache file, return the contents as a list of importable pools.
|
||||
* poolname or guid (but not both) are provided by the caller when trying
|
||||
* to import a specific pool.
|
||||
*/
|
||||
nvlist_t *
|
||||
zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile,
|
||||
char *poolname, uint64_t guid)
|
||||
{
|
||||
char *buf;
|
||||
int fd;
|
||||
struct stat64 statbuf;
|
||||
nvlist_t *raw, *src, *dst;
|
||||
nvlist_t *pools;
|
||||
nvpair_t *elem;
|
||||
char *name;
|
||||
uint64_t this_guid;
|
||||
boolean_t active;
|
||||
|
||||
verify(poolname == NULL || guid == 0);
|
||||
|
||||
if ((fd = open(cachefile, O_RDONLY)) < 0) {
|
||||
zfs_error_aux(hdl, "%s", strerror(errno));
|
||||
(void) zfs_error(hdl, EZFS_BADCACHE,
|
||||
dgettext(TEXT_DOMAIN, "failed to open cache file"));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (fstat64(fd, &statbuf) != 0) {
|
||||
zfs_error_aux(hdl, "%s", strerror(errno));
|
||||
(void) close(fd);
|
||||
(void) zfs_error(hdl, EZFS_BADCACHE,
|
||||
dgettext(TEXT_DOMAIN, "failed to get size of cache file"));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((buf = zfs_alloc(hdl, statbuf.st_size)) == NULL) {
|
||||
(void) close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
|
||||
(void) close(fd);
|
||||
free(buf);
|
||||
(void) zfs_error(hdl, EZFS_BADCACHE,
|
||||
dgettext(TEXT_DOMAIN,
|
||||
"failed to read cache file contents"));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
|
||||
if (nvlist_unpack(buf, statbuf.st_size, &raw, 0) != 0) {
|
||||
free(buf);
|
||||
(void) zfs_error(hdl, EZFS_BADCACHE,
|
||||
dgettext(TEXT_DOMAIN,
|
||||
"invalid or corrupt cache file contents"));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
/*
|
||||
* Go through and get the current state of the pools and refresh their
|
||||
* state.
|
||||
*/
|
||||
if (nvlist_alloc(&pools, 0, 0) != 0) {
|
||||
(void) no_memory(hdl);
|
||||
nvlist_free(raw);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
elem = NULL;
|
||||
while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) {
|
||||
verify(nvpair_value_nvlist(elem, &src) == 0);
|
||||
|
||||
verify(nvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME,
|
||||
&name) == 0);
|
||||
if (poolname != NULL && strcmp(poolname, name) != 0)
|
||||
continue;
|
||||
|
||||
verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
|
||||
&this_guid) == 0);
|
||||
if (guid != 0) {
|
||||
verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
|
||||
&this_guid) == 0);
|
||||
if (guid != this_guid)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pool_active(hdl, name, this_guid, &active) != 0) {
|
||||
nvlist_free(raw);
|
||||
nvlist_free(pools);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (active)
|
||||
continue;
|
||||
|
||||
if ((dst = refresh_config(hdl, src)) == NULL) {
|
||||
nvlist_free(raw);
|
||||
nvlist_free(pools);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) {
|
||||
(void) no_memory(hdl);
|
||||
nvlist_free(dst);
|
||||
nvlist_free(raw);
|
||||
nvlist_free(pools);
|
||||
return (NULL);
|
||||
}
|
||||
nvlist_free(dst);
|
||||
}
|
||||
|
||||
nvlist_free(raw);
|
||||
return (pools);
|
||||
}
|
||||
|
||||
|
||||
boolean_t
|
||||
find_guid(nvlist_t *nv, uint64_t guid)
|
||||
{
|
||||
@ -847,27 +1174,28 @@ find_guid(nvlist_t *nv, uint64_t guid)
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
typedef struct spare_cbdata {
|
||||
typedef struct aux_cbdata {
|
||||
const char *cb_type;
|
||||
uint64_t cb_guid;
|
||||
zpool_handle_t *cb_zhp;
|
||||
} spare_cbdata_t;
|
||||
} aux_cbdata_t;
|
||||
|
||||
static int
|
||||
find_spare(zpool_handle_t *zhp, void *data)
|
||||
find_aux(zpool_handle_t *zhp, void *data)
|
||||
{
|
||||
spare_cbdata_t *cbp = data;
|
||||
nvlist_t **spares;
|
||||
uint_t i, nspares;
|
||||
aux_cbdata_t *cbp = data;
|
||||
nvlist_t **list;
|
||||
uint_t i, count;
|
||||
uint64_t guid;
|
||||
nvlist_t *nvroot;
|
||||
|
||||
verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
|
||||
&nvroot) == 0);
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
|
||||
&spares, &nspares) == 0) {
|
||||
for (i = 0; i < nspares; i++) {
|
||||
verify(nvlist_lookup_uint64(spares[i],
|
||||
if (nvlist_lookup_nvlist_array(nvroot, cbp->cb_type,
|
||||
&list, &count) == 0) {
|
||||
for (i = 0; i < count; i++) {
|
||||
verify(nvlist_lookup_uint64(list[i],
|
||||
ZPOOL_CONFIG_GUID, &guid) == 0);
|
||||
if (guid == cbp->cb_guid) {
|
||||
cbp->cb_zhp = zhp;
|
||||
@ -896,7 +1224,7 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
|
||||
zpool_handle_t *zhp;
|
||||
nvlist_t *pool_config;
|
||||
uint64_t stateval, isspare;
|
||||
spare_cbdata_t cb = { 0 };
|
||||
aux_cbdata_t cb = { 0 };
|
||||
boolean_t isactive;
|
||||
|
||||
*inuse = B_FALSE;
|
||||
@ -914,7 +1242,7 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
|
||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID,
|
||||
&vdev_guid) == 0);
|
||||
|
||||
if (stateval != POOL_STATE_SPARE) {
|
||||
if (stateval != POOL_STATE_SPARE && stateval != POOL_STATE_L2CACHE) {
|
||||
verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
|
||||
&name) == 0);
|
||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
||||
@ -993,7 +1321,24 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
|
||||
*/
|
||||
cb.cb_zhp = NULL;
|
||||
cb.cb_guid = vdev_guid;
|
||||
if (zpool_iter(hdl, find_spare, &cb) == 1) {
|
||||
cb.cb_type = ZPOOL_CONFIG_SPARES;
|
||||
if (zpool_iter(hdl, find_aux, &cb) == 1) {
|
||||
name = (char *)zpool_get_name(cb.cb_zhp);
|
||||
ret = TRUE;
|
||||
} else {
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case POOL_STATE_L2CACHE:
|
||||
|
||||
/*
|
||||
* Check if any pool is currently using this l2cache device.
|
||||
*/
|
||||
cb.cb_zhp = NULL;
|
||||
cb.cb_guid = vdev_guid;
|
||||
cb.cb_type = ZPOOL_CONFIG_L2CACHE;
|
||||
if (zpool_iter(hdl, find_aux, &cb) == 1) {
|
||||
name = (char *)zpool_get_name(cb.cb_zhp);
|
||||
ret = TRUE;
|
||||
} else {
|
||||
@ -1008,6 +1353,8 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
|
||||
|
||||
if (ret) {
|
||||
if ((*namestr = zfs_strdup(hdl, name)) == NULL) {
|
||||
if (cb.cb_zhp)
|
||||
zpool_close(cb.cb_zhp);
|
||||
nvlist_free(config);
|
||||
return (-1);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2103
cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
Normal file
2103
cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -19,18 +19,16 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
/*
|
||||
* This file contains the functions which analyze the status of a pool. This
|
||||
* include both the status of an active pool, as well as the status exported
|
||||
* pools. Returns one of the ZPOOL_STATUS_* defines describing the status of
|
||||
* the pool. This status is independent (to a certain degree) from the state of
|
||||
* the pool. A pool's state descsribes only whether or not it is capable of
|
||||
* the pool. A pool's state describes only whether or not it is capable of
|
||||
* providing the necessary fault tolerance for data. The status describes the
|
||||
* overall status of devices. A pool that is online can still have a device
|
||||
* that is experiencing errors.
|
||||
@ -47,7 +45,7 @@
|
||||
#include "libzfs_impl.h"
|
||||
|
||||
/*
|
||||
* Message ID table. This must be kep in sync with the ZPOOL_STATUS_* defines
|
||||
* Message ID table. This must be kept in sync with the ZPOOL_STATUS_* defines
|
||||
* in libzfs.h. Note that there are some status results which go past the end
|
||||
* of this table, and hence have no associated message ID.
|
||||
*/
|
||||
@ -62,26 +60,10 @@ static char *zfs_msgid_table[] = {
|
||||
"ZFS-8000-8A",
|
||||
"ZFS-8000-9P",
|
||||
"ZFS-8000-A5",
|
||||
"ZFS-8000-EY"
|
||||
};
|
||||
|
||||
/*
|
||||
* If the pool is active, a certain class of static errors is overridden by the
|
||||
* faults as analayzed by FMA. These faults have separate knowledge articles,
|
||||
* and the article referred to by 'zpool status' must match that indicated by
|
||||
* the syslog error message. We override missing data as well as corrupt pool.
|
||||
*/
|
||||
static char *zfs_msgid_table_active[] = {
|
||||
"ZFS-8000-14",
|
||||
"ZFS-8000-D3", /* overridden */
|
||||
"ZFS-8000-D3", /* overridden */
|
||||
"ZFS-8000-4J",
|
||||
"ZFS-8000-5E",
|
||||
"ZFS-8000-6X",
|
||||
"ZFS-8000-CS", /* overridden */
|
||||
"ZFS-8000-8A",
|
||||
"ZFS-8000-9P",
|
||||
"ZFS-8000-CS", /* overridden */
|
||||
"ZFS-8000-EY",
|
||||
"ZFS-8000-HC",
|
||||
"ZFS-8000-JQ",
|
||||
"ZFS-8000-K4",
|
||||
};
|
||||
|
||||
#define NMSGID (sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0]))
|
||||
@ -94,11 +76,18 @@ vdev_missing(uint64_t state, uint64_t aux, uint64_t errs)
|
||||
aux == VDEV_AUX_OPEN_FAILED);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
vdev_faulted(uint64_t state, uint64_t aux, uint64_t errs)
|
||||
{
|
||||
return (state == VDEV_STATE_FAULTED);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
vdev_errors(uint64_t state, uint64_t aux, uint64_t errs)
|
||||
{
|
||||
return (errs != 0);
|
||||
return (state == VDEV_STATE_DEGRADED || errs != 0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -163,9 +152,9 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(uint64_t, uint64_t, uint64_t))
|
||||
* following:
|
||||
*
|
||||
* - Check for a complete and valid configuration
|
||||
* - Look for any missing devices in a non-replicated config
|
||||
* - Look for any faulted or missing devices in a non-replicated config
|
||||
* - Check for any data errors
|
||||
* - Check for any missing devices in a replicated config
|
||||
* - Check for any faulted or missing devices in a replicated config
|
||||
* - Look for any devices showing errors
|
||||
* - Check for any resilvering devices
|
||||
*
|
||||
@ -181,6 +170,7 @@ check_status(nvlist_t *config, boolean_t isimport)
|
||||
uint64_t nerr;
|
||||
uint64_t version;
|
||||
uint64_t stateval;
|
||||
uint64_t suspended;
|
||||
uint64_t hostid = 0;
|
||||
|
||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
|
||||
@ -215,8 +205,30 @@ check_status(nvlist_t *config, boolean_t isimport)
|
||||
return (ZPOOL_STATUS_BAD_GUID_SUM);
|
||||
|
||||
/*
|
||||
* Missing devices in non-replicated config.
|
||||
* Check whether the pool has suspended due to failed I/O.
|
||||
*/
|
||||
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_SUSPENDED,
|
||||
&suspended) == 0) {
|
||||
if (suspended == ZIO_FAILURE_MODE_CONTINUE)
|
||||
return (ZPOOL_STATUS_IO_FAILURE_CONTINUE);
|
||||
return (ZPOOL_STATUS_IO_FAILURE_WAIT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Could not read a log.
|
||||
*/
|
||||
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
|
||||
vs->vs_aux == VDEV_AUX_BAD_LOG) {
|
||||
return (ZPOOL_STATUS_BAD_LOG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bad devices in non-replicated config.
|
||||
*/
|
||||
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
|
||||
find_vdev_problem(nvroot, vdev_faulted))
|
||||
return (ZPOOL_STATUS_FAULTED_DEV_NR);
|
||||
|
||||
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
|
||||
find_vdev_problem(nvroot, vdev_missing))
|
||||
return (ZPOOL_STATUS_MISSING_DEV_NR);
|
||||
@ -244,6 +256,8 @@ check_status(nvlist_t *config, boolean_t isimport)
|
||||
/*
|
||||
* Missing devices in a replicated config.
|
||||
*/
|
||||
if (find_vdev_problem(nvroot, vdev_faulted))
|
||||
return (ZPOOL_STATUS_FAULTED_DEV_R);
|
||||
if (find_vdev_problem(nvroot, vdev_missing))
|
||||
return (ZPOOL_STATUS_MISSING_DEV_R);
|
||||
if (find_vdev_problem(nvroot, vdev_broken))
|
||||
@ -270,7 +284,7 @@ check_status(nvlist_t *config, boolean_t isimport)
|
||||
/*
|
||||
* Outdated, but usable, version
|
||||
*/
|
||||
if (version < ZFS_VERSION)
|
||||
if (version < SPA_VERSION)
|
||||
return (ZPOOL_STATUS_VERSION_OLDER);
|
||||
|
||||
return (ZPOOL_STATUS_OK);
|
||||
@ -284,7 +298,7 @@ zpool_get_status(zpool_handle_t *zhp, char **msgid)
|
||||
if (ret >= NMSGID)
|
||||
*msgid = NULL;
|
||||
else
|
||||
*msgid = zfs_msgid_table_active[ret];
|
||||
*msgid = zfs_msgid_table[ret];
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
@ -19,12 +19,10 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
/*
|
||||
* Internal utility routines for the ZFS library.
|
||||
*/
|
||||
@ -37,6 +35,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <sys/mnttab.h>
|
||||
#include <sys/mntent.h>
|
||||
#include <sys/types.h>
|
||||
@ -44,6 +44,7 @@
|
||||
#include <libzfs.h>
|
||||
|
||||
#include "libzfs_impl.h"
|
||||
#include "zfs_prop.h"
|
||||
|
||||
int
|
||||
libzfs_errno(libzfs_handle_t *hdl)
|
||||
@ -133,6 +134,14 @@ libzfs_error_description(libzfs_handle_t *hdl)
|
||||
return (dgettext(TEXT_DOMAIN, "unshare(1M) failed"));
|
||||
case EZFS_SHARENFSFAILED:
|
||||
return (dgettext(TEXT_DOMAIN, "share(1M) failed"));
|
||||
case EZFS_UNSHARESMBFAILED:
|
||||
return (dgettext(TEXT_DOMAIN, "smb remove share failed"));
|
||||
case EZFS_SHARESMBFAILED:
|
||||
return (dgettext(TEXT_DOMAIN, "smb add share failed"));
|
||||
case EZFS_ISCSISVCUNAVAIL:
|
||||
return (dgettext(TEXT_DOMAIN,
|
||||
"iscsitgt service need to be enabled by "
|
||||
"a privileged user"));
|
||||
case EZFS_DEVLINKS:
|
||||
return (dgettext(TEXT_DOMAIN, "failed to create /dev links"));
|
||||
case EZFS_PERM:
|
||||
@ -169,6 +178,38 @@ libzfs_error_description(libzfs_handle_t *hdl)
|
||||
"this pool operation"));
|
||||
case EZFS_NAMETOOLONG:
|
||||
return (dgettext(TEXT_DOMAIN, "dataset name is too long"));
|
||||
case EZFS_OPENFAILED:
|
||||
return (dgettext(TEXT_DOMAIN, "open failed"));
|
||||
case EZFS_NOCAP:
|
||||
return (dgettext(TEXT_DOMAIN,
|
||||
"disk capacity information could not be retrieved"));
|
||||
case EZFS_LABELFAILED:
|
||||
return (dgettext(TEXT_DOMAIN, "write of label failed"));
|
||||
case EZFS_BADWHO:
|
||||
return (dgettext(TEXT_DOMAIN, "invalid user/group"));
|
||||
case EZFS_BADPERM:
|
||||
return (dgettext(TEXT_DOMAIN, "invalid permission"));
|
||||
case EZFS_BADPERMSET:
|
||||
return (dgettext(TEXT_DOMAIN, "invalid permission set name"));
|
||||
case EZFS_NODELEGATION:
|
||||
return (dgettext(TEXT_DOMAIN, "delegated administration is "
|
||||
"disabled on pool"));
|
||||
case EZFS_PERMRDONLY:
|
||||
return (dgettext(TEXT_DOMAIN, "snapshot permissions cannot be"
|
||||
" modified"));
|
||||
case EZFS_BADCACHE:
|
||||
return (dgettext(TEXT_DOMAIN, "invalid or missing cache file"));
|
||||
case EZFS_ISL2CACHE:
|
||||
return (dgettext(TEXT_DOMAIN, "device is in use as a cache"));
|
||||
case EZFS_VDEVNOTSUP:
|
||||
return (dgettext(TEXT_DOMAIN, "vdev specification is not "
|
||||
"supported"));
|
||||
case EZFS_NOTSUP:
|
||||
return (dgettext(TEXT_DOMAIN, "operation not supported "
|
||||
"on this dataset"));
|
||||
case EZFS_ACTIVE_SPARE:
|
||||
return (dgettext(TEXT_DOMAIN, "pool has active shared spare "
|
||||
"device"));
|
||||
case EZFS_UNKNOWN:
|
||||
return (dgettext(TEXT_DOMAIN, "unknown error"));
|
||||
default:
|
||||
@ -249,6 +290,10 @@ zfs_common_error(libzfs_handle_t *hdl, int error, const char *fmt,
|
||||
zfs_verror(hdl, EZFS_PERM, fmt, ap);
|
||||
return (-1);
|
||||
|
||||
case ECANCELED:
|
||||
zfs_verror(hdl, EZFS_NODELEGATION, fmt, ap);
|
||||
return (-1);
|
||||
|
||||
case EIO:
|
||||
zfs_verror(hdl, EZFS_IO, fmt, ap);
|
||||
return (-1);
|
||||
@ -280,9 +325,9 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
switch (error) {
|
||||
case ENXIO:
|
||||
case ENODEV:
|
||||
zfs_verror(hdl, EZFS_IO, fmt, ap);
|
||||
break;
|
||||
|
||||
@ -308,11 +353,17 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
|
||||
"dataset is busy"));
|
||||
zfs_verror(hdl, EZFS_BUSY, fmt, ap);
|
||||
break;
|
||||
|
||||
case EROFS:
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"snapshot permissions cannot be modified"));
|
||||
zfs_verror(hdl, EZFS_PERMRDONLY, fmt, ap);
|
||||
break;
|
||||
case ENAMETOOLONG:
|
||||
zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap);
|
||||
break;
|
||||
|
||||
case ENOTSUP:
|
||||
zfs_verror(hdl, EZFS_BADVERSION, fmt, ap);
|
||||
break;
|
||||
default:
|
||||
zfs_error_aux(hdl, strerror(errno));
|
||||
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
|
||||
@ -361,7 +412,7 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
|
||||
|
||||
case EBUSY:
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy"));
|
||||
zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
|
||||
zfs_verror(hdl, EZFS_BUSY, fmt, ap);
|
||||
break;
|
||||
|
||||
case ENXIO:
|
||||
@ -382,6 +433,11 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
|
||||
zfs_verror(hdl, EZFS_POOL_INVALARG, fmt, ap);
|
||||
break;
|
||||
|
||||
case ENOSPC:
|
||||
case EDQUOT:
|
||||
zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
|
||||
return (-1);
|
||||
|
||||
default:
|
||||
zfs_error_aux(hdl, strerror(error));
|
||||
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
|
||||
@ -483,9 +539,8 @@ zfs_nicenum(uint64_t num, char *buf, size_t buflen)
|
||||
*/
|
||||
int i;
|
||||
for (i = 2; i >= 0; i--) {
|
||||
(void) snprintf(buf, buflen, "%.*f%c", i,
|
||||
(double)num / (1ULL << 10 * index), u);
|
||||
if (strlen(buf) <= 5)
|
||||
if (snprintf(buf, buflen, "%.*f%c", i,
|
||||
(double)num / (1ULL << 10 * index), u) <= 5)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -538,6 +593,9 @@ libzfs_init(void)
|
||||
|
||||
hdl->libzfs_sharetab = fopen(ZFS_EXPORTS_PATH, "r");
|
||||
|
||||
zfs_prop_init();
|
||||
zpool_prop_init();
|
||||
|
||||
return (hdl);
|
||||
}
|
||||
|
||||
@ -549,6 +607,10 @@ libzfs_fini(libzfs_handle_t *hdl)
|
||||
(void) fclose(hdl->libzfs_mnttab);
|
||||
if (hdl->libzfs_sharetab)
|
||||
(void) fclose(hdl->libzfs_sharetab);
|
||||
zfs_uninit_libshare(hdl);
|
||||
if (hdl->libzfs_log_str)
|
||||
(void) free(hdl->libzfs_log_str);
|
||||
zpool_free_handles(hdl);
|
||||
namespace_clear(hdl);
|
||||
free(hdl);
|
||||
}
|
||||
@ -565,6 +627,12 @@ zfs_get_handle(zfs_handle_t *zhp)
|
||||
return (zhp->zfs_hdl);
|
||||
}
|
||||
|
||||
zpool_handle_t *
|
||||
zfs_get_pool_handle(const zfs_handle_t *zhp)
|
||||
{
|
||||
return (zhp->zpool_hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a name, determine whether or not it's a valid path
|
||||
* (starts with '/' or "./"). If so, walk the mnttab trying
|
||||
@ -637,13 +705,14 @@ zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc)
|
||||
void
|
||||
zcmd_free_nvlists(zfs_cmd_t *zc)
|
||||
{
|
||||
free((void *)(uintptr_t)zc->zc_nvlist_conf);
|
||||
free((void *)(uintptr_t)zc->zc_nvlist_src);
|
||||
free((void *)(uintptr_t)zc->zc_nvlist_dst);
|
||||
}
|
||||
|
||||
int
|
||||
zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl,
|
||||
size_t *size)
|
||||
static int
|
||||
zcmd_write_nvlist_com(libzfs_handle_t *hdl, uint64_t *outnv, uint64_t *outlen,
|
||||
nvlist_t *nvl)
|
||||
{
|
||||
char *packed;
|
||||
size_t len;
|
||||
@ -655,14 +724,26 @@ zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl,
|
||||
|
||||
verify(nvlist_pack(nvl, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
|
||||
|
||||
zc->zc_nvlist_src = (uint64_t)(uintptr_t)packed;
|
||||
zc->zc_nvlist_src_size = len;
|
||||
*outnv = (uint64_t)(uintptr_t)packed;
|
||||
*outlen = len;
|
||||
|
||||
if (size)
|
||||
*size = len;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
zcmd_write_conf_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
|
||||
{
|
||||
return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_conf,
|
||||
&zc->zc_nvlist_conf_size, nvl));
|
||||
}
|
||||
|
||||
int
|
||||
zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
|
||||
{
|
||||
return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_src,
|
||||
&zc->zc_nvlist_src_size, nvl));
|
||||
}
|
||||
|
||||
/*
|
||||
* Unpacks an nvlist from the ZFS ioctl command structure.
|
||||
*/
|
||||
@ -676,10 +757,32 @@ zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
zfs_print_prop_headers(libzfs_get_cbdata_t *cbp)
|
||||
int
|
||||
zfs_ioctl(libzfs_handle_t *hdl, unsigned long request, zfs_cmd_t *zc)
|
||||
{
|
||||
zfs_proplist_t *pl = cbp->cb_proplist;
|
||||
int error;
|
||||
|
||||
zc->zc_history = (uint64_t)(uintptr_t)hdl->libzfs_log_str;
|
||||
error = ioctl(hdl->libzfs_fd, request, zc);
|
||||
if (hdl->libzfs_log_str) {
|
||||
free(hdl->libzfs_log_str);
|
||||
hdl->libzfs_log_str = NULL;
|
||||
}
|
||||
zc->zc_history = 0;
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* ================================================================
|
||||
* API shared by zfs and zpool property management
|
||||
* ================================================================
|
||||
*/
|
||||
|
||||
static void
|
||||
zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
|
||||
{
|
||||
zprop_list_t *pl = cbp->cb_proplist;
|
||||
int i;
|
||||
char *title;
|
||||
size_t len;
|
||||
@ -711,8 +814,12 @@ zfs_print_prop_headers(libzfs_get_cbdata_t *cbp)
|
||||
/*
|
||||
* 'PROPERTY' column
|
||||
*/
|
||||
if (pl->pl_prop != ZFS_PROP_INVAL) {
|
||||
len = strlen(zfs_prop_to_name(pl->pl_prop));
|
||||
if (pl->pl_prop != ZPROP_INVAL) {
|
||||
const char *propname = (type == ZFS_TYPE_POOL) ?
|
||||
zpool_prop_to_name(pl->pl_prop) :
|
||||
zfs_prop_to_name(pl->pl_prop);
|
||||
|
||||
len = strlen(propname);
|
||||
if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
|
||||
cbp->cb_colwidths[GET_COL_PROPERTY] = len;
|
||||
} else {
|
||||
@ -731,7 +838,8 @@ zfs_print_prop_headers(libzfs_get_cbdata_t *cbp)
|
||||
/*
|
||||
* 'NAME' and 'SOURCE' columns
|
||||
*/
|
||||
if (pl->pl_prop == ZFS_PROP_NAME &&
|
||||
if (pl->pl_prop == (type == ZFS_TYPE_POOL ? ZPOOL_PROP_NAME :
|
||||
ZFS_PROP_NAME) &&
|
||||
pl->pl_width > cbp->cb_colwidths[GET_COL_NAME]) {
|
||||
cbp->cb_colwidths[GET_COL_NAME] = pl->pl_width;
|
||||
cbp->cb_colwidths[GET_COL_SOURCE] = pl->pl_width +
|
||||
@ -777,8 +885,8 @@ zfs_print_prop_headers(libzfs_get_cbdata_t *cbp)
|
||||
* structure.
|
||||
*/
|
||||
void
|
||||
libzfs_print_one_property(const char *name, libzfs_get_cbdata_t *cbp,
|
||||
const char *propname, const char *value, zfs_source_t sourcetype,
|
||||
zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp,
|
||||
const char *propname, const char *value, zprop_source_t sourcetype,
|
||||
const char *source)
|
||||
{
|
||||
int i;
|
||||
@ -792,7 +900,7 @@ libzfs_print_one_property(const char *name, libzfs_get_cbdata_t *cbp,
|
||||
return;
|
||||
|
||||
if (cbp->cb_first)
|
||||
zfs_print_prop_headers(cbp);
|
||||
zprop_print_headers(cbp, cbp->cb_type);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
switch (cbp->cb_columns[i]) {
|
||||
@ -810,23 +918,23 @@ libzfs_print_one_property(const char *name, libzfs_get_cbdata_t *cbp,
|
||||
|
||||
case GET_COL_SOURCE:
|
||||
switch (sourcetype) {
|
||||
case ZFS_SRC_NONE:
|
||||
case ZPROP_SRC_NONE:
|
||||
str = "-";
|
||||
break;
|
||||
|
||||
case ZFS_SRC_DEFAULT:
|
||||
case ZPROP_SRC_DEFAULT:
|
||||
str = "default";
|
||||
break;
|
||||
|
||||
case ZFS_SRC_LOCAL:
|
||||
case ZPROP_SRC_LOCAL:
|
||||
str = "local";
|
||||
break;
|
||||
|
||||
case ZFS_SRC_TEMPORARY:
|
||||
case ZPROP_SRC_TEMPORARY:
|
||||
str = "temporary";
|
||||
break;
|
||||
|
||||
case ZFS_SRC_INHERITED:
|
||||
case ZPROP_SRC_INHERITED:
|
||||
(void) snprintf(buf, sizeof (buf),
|
||||
"inherited from %s", source);
|
||||
str = buf;
|
||||
@ -851,3 +959,451 @@ libzfs_print_one_property(const char *name, libzfs_get_cbdata_t *cbp,
|
||||
|
||||
(void) printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a numeric suffix, convert the value into a number of bits that the
|
||||
* resulting value must be shifted.
|
||||
*/
|
||||
static int
|
||||
str2shift(libzfs_handle_t *hdl, const char *buf)
|
||||
{
|
||||
const char *ends = "BKMGTPEZ";
|
||||
int i;
|
||||
|
||||
if (buf[0] == '\0')
|
||||
return (0);
|
||||
for (i = 0; i < strlen(ends); i++) {
|
||||
if (toupper(buf[0]) == ends[i])
|
||||
break;
|
||||
}
|
||||
if (i == strlen(ends)) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"invalid numeric suffix '%s'"), buf);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We want to allow trailing 'b' characters for 'GB' or 'Mb'. But don't
|
||||
* allow 'BB' - that's just weird.
|
||||
*/
|
||||
if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
|
||||
toupper(buf[0]) != 'B'))
|
||||
return (10*i);
|
||||
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"invalid numeric suffix '%s'"), buf);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string of the form '100G' into a real number. Used when setting
|
||||
* properties or creating a volume. 'buf' is used to place an extended error
|
||||
* message for the caller to use.
|
||||
*/
|
||||
int
|
||||
zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
|
||||
{
|
||||
char *end;
|
||||
int shift;
|
||||
|
||||
*num = 0;
|
||||
|
||||
/* Check to see if this looks like a number. */
|
||||
if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
|
||||
if (hdl)
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"bad numeric value '%s'"), value);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Rely on stroll() to process the numeric portion. */
|
||||
errno = 0;
|
||||
*num = strtoll(value, &end, 10);
|
||||
|
||||
/*
|
||||
* Check for ERANGE, which indicates that the value is too large to fit
|
||||
* in a 64-bit value.
|
||||
*/
|
||||
if (errno == ERANGE) {
|
||||
if (hdl)
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"numeric value is too large"));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have a decimal value, then do the computation with floating
|
||||
* point arithmetic. Otherwise, use standard arithmetic.
|
||||
*/
|
||||
if (*end == '.') {
|
||||
double fval = strtod(value, &end);
|
||||
|
||||
if ((shift = str2shift(hdl, end)) == -1)
|
||||
return (-1);
|
||||
|
||||
fval *= pow(2, shift);
|
||||
|
||||
if (fval > UINT64_MAX) {
|
||||
if (hdl)
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"numeric value is too large"));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*num = (uint64_t)fval;
|
||||
} else {
|
||||
if ((shift = str2shift(hdl, end)) == -1)
|
||||
return (-1);
|
||||
|
||||
/* Check for overflow */
|
||||
if (shift >= 64 || (*num << shift) >> shift != *num) {
|
||||
if (hdl)
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"numeric value is too large"));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*num <<= shift;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a propname=value nvpair to set, parse any numeric properties
|
||||
* (index, boolean, etc) if they are specified as strings and add the
|
||||
* resulting nvpair to the returned nvlist.
|
||||
*
|
||||
* At the DSL layer, all properties are either 64-bit numbers or strings.
|
||||
* We want the user to be able to ignore this fact and specify properties
|
||||
* as native values (numbers, for example) or as strings (to simplify
|
||||
* command line utilities). This also handles converting index types
|
||||
* (compression, checksum, etc) from strings to their on-disk index.
|
||||
*/
|
||||
int
|
||||
zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
|
||||
zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp,
|
||||
const char *errbuf)
|
||||
{
|
||||
data_type_t datatype = nvpair_type(elem);
|
||||
zprop_type_t proptype;
|
||||
const char *propname;
|
||||
char *value;
|
||||
boolean_t isnone = B_FALSE;
|
||||
|
||||
if (type == ZFS_TYPE_POOL) {
|
||||
proptype = zpool_prop_get_type(prop);
|
||||
propname = zpool_prop_to_name(prop);
|
||||
} else {
|
||||
proptype = zfs_prop_get_type(prop);
|
||||
propname = zfs_prop_to_name(prop);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert any properties to the internal DSL value types.
|
||||
*/
|
||||
*svalp = NULL;
|
||||
*ivalp = 0;
|
||||
|
||||
switch (proptype) {
|
||||
case PROP_TYPE_STRING:
|
||||
if (datatype != DATA_TYPE_STRING) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"'%s' must be a string"), nvpair_name(elem));
|
||||
goto error;
|
||||
}
|
||||
(void) nvpair_value_string(elem, svalp);
|
||||
if (strlen(*svalp) >= ZFS_MAXPROPLEN) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"'%s' is too long"), nvpair_name(elem));
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_TYPE_NUMBER:
|
||||
if (datatype == DATA_TYPE_STRING) {
|
||||
(void) nvpair_value_string(elem, &value);
|
||||
if (strcmp(value, "none") == 0) {
|
||||
isnone = B_TRUE;
|
||||
} else if (zfs_nicestrtonum(hdl, value, ivalp)
|
||||
!= 0) {
|
||||
goto error;
|
||||
}
|
||||
} else if (datatype == DATA_TYPE_UINT64) {
|
||||
(void) nvpair_value_uint64(elem, ivalp);
|
||||
} else {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"'%s' must be a number"), nvpair_name(elem));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Quota special: force 'none' and don't allow 0.
|
||||
*/
|
||||
if ((type & ZFS_TYPE_DATASET) && *ivalp == 0 && !isnone &&
|
||||
(prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_REFQUOTA)) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"use 'none' to disable quota/refquota"));
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_TYPE_INDEX:
|
||||
if (datatype != DATA_TYPE_STRING) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"'%s' must be a string"), nvpair_name(elem));
|
||||
goto error;
|
||||
}
|
||||
|
||||
(void) nvpair_value_string(elem, &value);
|
||||
|
||||
if (zprop_string_to_index(prop, value, ivalp, type) != 0) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"'%s' must be one of '%s'"), propname,
|
||||
zprop_values(prop, type));
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the result to our return set of properties.
|
||||
*/
|
||||
if (*svalp != NULL) {
|
||||
if (nvlist_add_string(ret, propname, *svalp) != 0) {
|
||||
(void) no_memory(hdl);
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
if (nvlist_add_uint64(ret, propname, *ivalp) != 0) {
|
||||
(void) no_memory(hdl);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
error:
|
||||
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
|
||||
zfs_type_t type)
|
||||
{
|
||||
int prop;
|
||||
zprop_list_t *entry;
|
||||
|
||||
prop = zprop_name_to_prop(propname, type);
|
||||
|
||||
if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type))
|
||||
prop = ZPROP_INVAL;
|
||||
|
||||
/*
|
||||
* When no property table entry can be found, return failure if
|
||||
* this is a pool property or if this isn't a user-defined
|
||||
* dataset property,
|
||||
*/
|
||||
if (prop == ZPROP_INVAL && (type == ZFS_TYPE_POOL ||
|
||||
!zfs_prop_user(propname))) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"invalid property '%s'"), propname);
|
||||
return (zfs_error(hdl, EZFS_BADPROP,
|
||||
dgettext(TEXT_DOMAIN, "bad property list")));
|
||||
}
|
||||
|
||||
if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
|
||||
return (-1);
|
||||
|
||||
entry->pl_prop = prop;
|
||||
if (prop == ZPROP_INVAL) {
|
||||
if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) == NULL) {
|
||||
free(entry);
|
||||
return (-1);
|
||||
}
|
||||
entry->pl_width = strlen(propname);
|
||||
} else {
|
||||
entry->pl_width = zprop_width(prop, &entry->pl_fixed,
|
||||
type);
|
||||
}
|
||||
|
||||
*listp = entry;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a comma-separated list of properties, construct a property list
|
||||
* containing both user-defined and native properties. This function will
|
||||
* return a NULL list if 'all' is specified, which can later be expanded
|
||||
* by zprop_expand_list().
|
||||
*/
|
||||
int
|
||||
zprop_get_list(libzfs_handle_t *hdl, char *props, zprop_list_t **listp,
|
||||
zfs_type_t type)
|
||||
{
|
||||
*listp = NULL;
|
||||
|
||||
/*
|
||||
* If 'all' is specified, return a NULL list.
|
||||
*/
|
||||
if (strcmp(props, "all") == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* If no props were specified, return an error.
|
||||
*/
|
||||
if (props[0] == '\0') {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"no properties specified"));
|
||||
return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
|
||||
"bad property list")));
|
||||
}
|
||||
|
||||
/*
|
||||
* It would be nice to use getsubopt() here, but the inclusion of column
|
||||
* aliases makes this more effort than it's worth.
|
||||
*/
|
||||
while (*props != '\0') {
|
||||
size_t len;
|
||||
char *p;
|
||||
char c;
|
||||
|
||||
if ((p = strchr(props, ',')) == NULL) {
|
||||
len = strlen(props);
|
||||
p = props + len;
|
||||
} else {
|
||||
len = p - props;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for empty options.
|
||||
*/
|
||||
if (len == 0) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"empty property name"));
|
||||
return (zfs_error(hdl, EZFS_BADPROP,
|
||||
dgettext(TEXT_DOMAIN, "bad property list")));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check all regular property names.
|
||||
*/
|
||||
c = props[len];
|
||||
props[len] = '\0';
|
||||
|
||||
if (strcmp(props, "space") == 0) {
|
||||
static char *spaceprops[] = {
|
||||
"name", "avail", "used", "usedbysnapshots",
|
||||
"usedbydataset", "usedbyrefreservation",
|
||||
"usedbychildren", NULL
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; spaceprops[i]; i++) {
|
||||
if (addlist(hdl, spaceprops[i], listp, type))
|
||||
return (-1);
|
||||
listp = &(*listp)->pl_next;
|
||||
}
|
||||
} else {
|
||||
if (addlist(hdl, props, listp, type))
|
||||
return (-1);
|
||||
listp = &(*listp)->pl_next;
|
||||
}
|
||||
|
||||
props = p;
|
||||
if (c == ',')
|
||||
props++;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
zprop_free_list(zprop_list_t *pl)
|
||||
{
|
||||
zprop_list_t *next;
|
||||
|
||||
while (pl != NULL) {
|
||||
next = pl->pl_next;
|
||||
free(pl->pl_user_prop);
|
||||
free(pl);
|
||||
pl = next;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct expand_data {
|
||||
zprop_list_t **last;
|
||||
libzfs_handle_t *hdl;
|
||||
zfs_type_t type;
|
||||
} expand_data_t;
|
||||
|
||||
int
|
||||
zprop_expand_list_cb(int prop, void *cb)
|
||||
{
|
||||
zprop_list_t *entry;
|
||||
expand_data_t *edp = cb;
|
||||
|
||||
if ((entry = zfs_alloc(edp->hdl, sizeof (zprop_list_t))) == NULL)
|
||||
return (ZPROP_INVAL);
|
||||
|
||||
entry->pl_prop = prop;
|
||||
entry->pl_width = zprop_width(prop, &entry->pl_fixed, edp->type);
|
||||
entry->pl_all = B_TRUE;
|
||||
|
||||
*(edp->last) = entry;
|
||||
edp->last = &entry->pl_next;
|
||||
|
||||
return (ZPROP_CONT);
|
||||
}
|
||||
|
||||
int
|
||||
zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, zfs_type_t type)
|
||||
{
|
||||
zprop_list_t *entry;
|
||||
zprop_list_t **last;
|
||||
expand_data_t exp;
|
||||
|
||||
if (*plp == NULL) {
|
||||
/*
|
||||
* If this is the very first time we've been called for an 'all'
|
||||
* specification, expand the list to include all native
|
||||
* properties.
|
||||
*/
|
||||
last = plp;
|
||||
|
||||
exp.last = last;
|
||||
exp.hdl = hdl;
|
||||
exp.type = type;
|
||||
|
||||
if (zprop_iter_common(zprop_expand_list_cb, &exp, B_FALSE,
|
||||
B_FALSE, type) == ZPROP_INVAL)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Add 'name' to the beginning of the list, which is handled
|
||||
* specially.
|
||||
*/
|
||||
if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
|
||||
return (-1);
|
||||
|
||||
entry->pl_prop = (type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME :
|
||||
ZFS_PROP_NAME;
|
||||
entry->pl_width = zprop_width(entry->pl_prop,
|
||||
&entry->pl_fixed, type);
|
||||
entry->pl_all = B_TRUE;
|
||||
entry->pl_next = *plp;
|
||||
*plp = entry;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered,
|
||||
zfs_type_t type)
|
||||
{
|
||||
return (zprop_iter_common(func, cb, show_all, ordered, type));
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -101,20 +101,24 @@ void
|
||||
zmutex_init(kmutex_t *mp)
|
||||
{
|
||||
mp->m_owner = NULL;
|
||||
mp->initialized = B_TRUE;
|
||||
(void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
zmutex_destroy(kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mp->initialized == B_TRUE);
|
||||
ASSERT(mp->m_owner == NULL);
|
||||
(void) _mutex_destroy(&(mp)->m_lock);
|
||||
mp->m_owner = (void *)-1UL;
|
||||
mp->initialized = B_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
mutex_enter(kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mp->initialized == B_TRUE);
|
||||
ASSERT(mp->m_owner != (void *)-1UL);
|
||||
ASSERT(mp->m_owner != curthread);
|
||||
VERIFY(mutex_lock(&mp->m_lock) == 0);
|
||||
@ -125,6 +129,7 @@ mutex_enter(kmutex_t *mp)
|
||||
int
|
||||
mutex_tryenter(kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mp->initialized == B_TRUE);
|
||||
ASSERT(mp->m_owner != (void *)-1UL);
|
||||
if (mutex_trylock(&mp->m_lock) == 0) {
|
||||
ASSERT(mp->m_owner == NULL);
|
||||
@ -138,6 +143,7 @@ mutex_tryenter(kmutex_t *mp)
|
||||
void
|
||||
mutex_exit(kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mp->initialized == B_TRUE);
|
||||
ASSERT(mp->m_owner == curthread);
|
||||
mp->m_owner = NULL;
|
||||
VERIFY(mutex_unlock(&mp->m_lock) == 0);
|
||||
@ -146,6 +152,7 @@ mutex_exit(kmutex_t *mp)
|
||||
void *
|
||||
mutex_owner(kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mp->initialized == B_TRUE);
|
||||
return (mp->m_owner);
|
||||
}
|
||||
|
||||
@ -160,7 +167,7 @@ rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
|
||||
{
|
||||
rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
|
||||
rwlp->rw_owner = NULL;
|
||||
rwlp->rw_count = 0;
|
||||
rwlp->initialized = B_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
@ -168,22 +175,23 @@ rw_destroy(krwlock_t *rwlp)
|
||||
{
|
||||
rwlock_destroy(&rwlp->rw_lock);
|
||||
rwlp->rw_owner = (void *)-1UL;
|
||||
rwlp->rw_count = -2;
|
||||
rwlp->initialized = B_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
rw_enter(krwlock_t *rwlp, krw_t rw)
|
||||
{
|
||||
//ASSERT(!RW_LOCK_HELD(rwlp));
|
||||
ASSERT(rwlp->initialized == B_TRUE);
|
||||
ASSERT(rwlp->rw_owner != (void *)-1UL);
|
||||
ASSERT(rwlp->rw_owner != curthread);
|
||||
|
||||
if (rw == RW_READER) {
|
||||
(void) rw_rdlock(&rwlp->rw_lock);
|
||||
VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
|
||||
ASSERT(rwlp->rw_count >= 0);
|
||||
atomic_add_int(&rwlp->rw_count, 1);
|
||||
} else {
|
||||
(void) rw_wrlock(&rwlp->rw_lock);
|
||||
VERIFY(rw_wrlock(&rwlp->rw_lock) == 0);
|
||||
ASSERT(rwlp->rw_count == 0);
|
||||
rwlp->rw_count = -1;
|
||||
rwlp->rw_owner = curthread;
|
||||
@ -193,6 +201,7 @@ rw_enter(krwlock_t *rwlp, krw_t rw)
|
||||
void
|
||||
rw_exit(krwlock_t *rwlp)
|
||||
{
|
||||
ASSERT(rwlp->initialized == B_TRUE);
|
||||
ASSERT(rwlp->rw_owner != (void *)-1UL);
|
||||
|
||||
if (rwlp->rw_owner == curthread) {
|
||||
@ -205,7 +214,7 @@ rw_exit(krwlock_t *rwlp)
|
||||
ASSERT(rwlp->rw_count > 0);
|
||||
atomic_add_int(&rwlp->rw_count, -1);
|
||||
}
|
||||
(void) rw_unlock(&rwlp->rw_lock);
|
||||
VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -213,6 +222,7 @@ rw_tryenter(krwlock_t *rwlp, krw_t rw)
|
||||
{
|
||||
int rv;
|
||||
|
||||
ASSERT(rwlp->initialized == B_TRUE);
|
||||
ASSERT(rwlp->rw_owner != (void *)-1UL);
|
||||
ASSERT(rwlp->rw_owner != curthread);
|
||||
|
||||
@ -241,6 +251,7 @@ rw_tryenter(krwlock_t *rwlp, krw_t rw)
|
||||
int
|
||||
rw_tryupgrade(krwlock_t *rwlp)
|
||||
{
|
||||
ASSERT(rwlp->initialized == B_TRUE);
|
||||
ASSERT(rwlp->rw_owner != (void *)-1UL);
|
||||
|
||||
return (0);
|
||||
@ -422,9 +433,10 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
|
||||
int x3, vnode_t *startvp)
|
||||
int x3, vnode_t *startvp, int fd)
|
||||
{
|
||||
char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
|
||||
int ret;
|
||||
@ -432,6 +444,7 @@ vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
|
||||
ASSERT(startvp == rootdir);
|
||||
(void) sprintf(realpath, "/%s", path);
|
||||
|
||||
/* fd ignored for now, need if want to simulate nbmand support */
|
||||
ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
|
||||
|
||||
umem_free(realpath, strlen(path) + 2);
|
||||
@ -469,7 +482,7 @@ vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
|
||||
}
|
||||
|
||||
void
|
||||
vn_close(vnode_t *vp)
|
||||
vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td)
|
||||
{
|
||||
close(vp->v_fd);
|
||||
spa_strfree(vp->v_path);
|
||||
@ -657,7 +670,8 @@ kobj_open_file(char *name)
|
||||
vnode_t *vp;
|
||||
|
||||
/* set vp as the _fd field of the file */
|
||||
if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir) != 0)
|
||||
if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
|
||||
-1) != 0)
|
||||
return ((void *)-1UL);
|
||||
|
||||
file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
|
||||
@ -679,7 +693,7 @@ kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
|
||||
void
|
||||
kobj_close_file(struct _buf *file)
|
||||
{
|
||||
vn_close((vnode_t *)file->_fd);
|
||||
vn_close((vnode_t *)file->_fd, 0, NULL, NULL);
|
||||
umem_free(file, sizeof (struct _buf));
|
||||
}
|
||||
|
||||
@ -690,7 +704,7 @@ kobj_get_filesize(struct _buf *file, uint64_t *size)
|
||||
vnode_t *vp = (vnode_t *)file->_fd;
|
||||
|
||||
if (fstat64(vp->v_fd, &st) == -1) {
|
||||
vn_close(vp);
|
||||
vn_close(vp, 0, NULL, NULL);
|
||||
return (errno);
|
||||
}
|
||||
*size = st.st_size;
|
||||
@ -746,10 +760,11 @@ highbit(ulong_t i)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int random_fd = -1, urandom_fd = -1;
|
||||
|
||||
static int
|
||||
random_get_bytes_common(uint8_t *ptr, size_t len, char *devname)
|
||||
random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
|
||||
{
|
||||
int fd = open(devname, O_RDONLY);
|
||||
size_t resid = len;
|
||||
ssize_t bytes;
|
||||
|
||||
@ -757,26 +772,24 @@ random_get_bytes_common(uint8_t *ptr, size_t len, char *devname)
|
||||
|
||||
while (resid != 0) {
|
||||
bytes = read(fd, ptr, resid);
|
||||
ASSERT(bytes >= 0);
|
||||
ASSERT3S(bytes, >=, 0);
|
||||
ptr += bytes;
|
||||
resid -= bytes;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
random_get_bytes(uint8_t *ptr, size_t len)
|
||||
{
|
||||
return (random_get_bytes_common(ptr, len, "/dev/random"));
|
||||
return (random_get_bytes_common(ptr, len, random_fd));
|
||||
}
|
||||
|
||||
int
|
||||
random_get_pseudo_bytes(uint8_t *ptr, size_t len)
|
||||
{
|
||||
return (random_get_bytes_common(ptr, len, "/dev/urandom"));
|
||||
return (random_get_bytes_common(ptr, len, urandom_fd));
|
||||
}
|
||||
|
||||
int
|
||||
@ -815,7 +828,11 @@ kernel_init(int mode)
|
||||
dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
|
||||
(double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
|
||||
|
||||
snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid());
|
||||
snprintf(hw_serial, sizeof (hw_serial), "%lu",
|
||||
(unsigned long)gethostid());
|
||||
|
||||
VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
|
||||
VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
|
||||
|
||||
spa_init(mode);
|
||||
}
|
||||
@ -824,6 +841,12 @@ void
|
||||
kernel_fini(void)
|
||||
{
|
||||
spa_fini();
|
||||
|
||||
close(random_fd);
|
||||
close(urandom_fd);
|
||||
|
||||
random_fd = -1;
|
||||
urandom_fd = -1;
|
||||
}
|
||||
|
||||
int
|
||||
@ -850,3 +873,62 @@ z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
uid_t
|
||||
crgetuid(cred_t *cr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
gid_t
|
||||
crgetgid(cred_t *cr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
crgetngroups(cred_t *cr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
gid_t *
|
||||
crgetgroups(cred_t *cr)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
ksiddomain_t *
|
||||
ksid_lookupdomain(const char *dom)
|
||||
{
|
||||
ksiddomain_t *kd;
|
||||
|
||||
kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
|
||||
kd->kd_name = spa_strdup(dom);
|
||||
return (kd);
|
||||
}
|
||||
|
||||
void
|
||||
ksiddomain_rele(ksiddomain_t *ksid)
|
||||
{
|
||||
spa_strfree(ksid->kd_name);
|
||||
umem_free(ksid, sizeof (ksiddomain_t));
|
||||
}
|
||||
|
@ -19,15 +19,13 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ZFS_CONTEXT_H
|
||||
#define _SYS_ZFS_CONTEXT_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -64,6 +62,7 @@ extern "C" {
|
||||
#include <fsshare.h>
|
||||
#include <sys/note.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cred.h>
|
||||
#include <sys/atomic.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/bitmap.h>
|
||||
@ -78,8 +77,10 @@ extern "C" {
|
||||
#include <sys/debug.h>
|
||||
#include <sys/sdt.h>
|
||||
#include <sys/kstat.h>
|
||||
#include <sys/u8_textprep.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/sysevent/eventdefs.h>
|
||||
#include <machine/atomic.h>
|
||||
|
||||
#define ZFS_EXPORTS_PATH "/etc/zfs/exports"
|
||||
@ -116,11 +117,12 @@ extern void vcmn_err(int, const char *, __va_list);
|
||||
extern void panic(const char *, ...);
|
||||
extern void vpanic(const char *, __va_list);
|
||||
|
||||
#define fm_panic panic
|
||||
|
||||
/* This definition is copied from assert.h. */
|
||||
#if defined(__STDC__)
|
||||
#if __STDC_VERSION__ - 0 >= 199901L
|
||||
#define verify(EX) (void)((EX) || \
|
||||
(__assert_c99(#EX, __FILE__, __LINE__, __func__), 0))
|
||||
#define verify(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
|
||||
#else
|
||||
#define verify(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
|
||||
#endif /* __STDC_VERSION__ - 0 >= 199901L */
|
||||
@ -167,11 +169,16 @@ _NOTE(CONSTCOND) } while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dtrace SDT probes have different signatures in userland than they do in
|
||||
* DTrace SDT probes have different signatures in userland than they do in
|
||||
* kernel. If they're being used in kernel code, re-define them out of
|
||||
* existence for their counterparts in libzpool.
|
||||
*/
|
||||
|
||||
#ifdef DTRACE_PROBE
|
||||
#undef DTRACE_PROBE
|
||||
#define DTRACE_PROBE(a) ((void)0)
|
||||
#endif /* DTRACE_PROBE */
|
||||
|
||||
#ifdef DTRACE_PROBE1
|
||||
#undef DTRACE_PROBE1
|
||||
#define DTRACE_PROBE1(a, b, c) ((void)0)
|
||||
@ -212,8 +219,9 @@ extern kthread_t *zk_thread_create(void (*func)(), void *arg);
|
||||
* Mutexes
|
||||
*/
|
||||
typedef struct kmutex {
|
||||
void *m_owner;
|
||||
mutex_t m_lock;
|
||||
void *m_owner;
|
||||
boolean_t initialized;
|
||||
mutex_t m_lock;
|
||||
} kmutex_t;
|
||||
|
||||
#define MUTEX_DEFAULT USYNC_THREAD
|
||||
@ -243,6 +251,7 @@ extern void *mutex_owner(kmutex_t *mp);
|
||||
typedef struct krwlock {
|
||||
int rw_count;
|
||||
void *rw_owner;
|
||||
boolean_t initialized;
|
||||
rwlock_t rw_lock;
|
||||
} krwlock_t;
|
||||
|
||||
@ -253,6 +262,7 @@ typedef int krw_t;
|
||||
#define RW_DEFAULT USYNC_THREAD
|
||||
|
||||
#undef RW_READ_HELD
|
||||
#define RW_READ_HELD(x) ((x)->rw_owner == NULL && (x)->rw_count > 0)
|
||||
|
||||
#undef RW_WRITE_HELD
|
||||
#define RW_WRITE_HELD(x) ((x)->rw_owner == curthread)
|
||||
@ -267,6 +277,11 @@ extern void rw_exit(krwlock_t *rwlp);
|
||||
extern int rw_lock_held(krwlock_t *rwlp);
|
||||
#define rw_downgrade(rwlp) do { } while (0)
|
||||
|
||||
extern uid_t crgetuid(cred_t *cr);
|
||||
extern gid_t crgetgid(cred_t *cr);
|
||||
extern int crgetngroups(cred_t *cr);
|
||||
extern gid_t *crgetgroups(cred_t *cr);
|
||||
|
||||
/*
|
||||
* Condition variables
|
||||
*/
|
||||
@ -285,6 +300,7 @@ extern void cv_broadcast(kcondvar_t *cv);
|
||||
* Kernel memory
|
||||
*/
|
||||
#define KM_SLEEP UMEM_NOFAIL
|
||||
#define KM_PUSHPAGE KM_SLEEP
|
||||
#define KM_NOSLEEP UMEM_DEFAULT
|
||||
#define KMC_NODEBUG UMC_NODEBUG
|
||||
#define kmem_alloc(_s, _f) umem_alloc(_s, _f)
|
||||
@ -322,6 +338,9 @@ extern void taskq_destroy(taskq_t *);
|
||||
extern void taskq_wait(taskq_t *);
|
||||
extern int taskq_member(taskq_t *, void *);
|
||||
|
||||
#define XVA_MAPSIZE 3
|
||||
#define XVA_MAGIC 0x78766174
|
||||
|
||||
/*
|
||||
* vnodes
|
||||
*/
|
||||
@ -331,44 +350,93 @@ typedef struct vnode {
|
||||
char *v_path;
|
||||
} vnode_t;
|
||||
|
||||
|
||||
typedef struct xoptattr {
|
||||
timestruc_t xoa_createtime; /* Create time of file */
|
||||
uint8_t xoa_archive;
|
||||
uint8_t xoa_system;
|
||||
uint8_t xoa_readonly;
|
||||
uint8_t xoa_hidden;
|
||||
uint8_t xoa_nounlink;
|
||||
uint8_t xoa_immutable;
|
||||
uint8_t xoa_appendonly;
|
||||
uint8_t xoa_nodump;
|
||||
uint8_t xoa_settable;
|
||||
uint8_t xoa_opaque;
|
||||
uint8_t xoa_av_quarantined;
|
||||
uint8_t xoa_av_modified;
|
||||
} xoptattr_t;
|
||||
|
||||
typedef struct vattr {
|
||||
uint_t va_mask; /* bit-mask of attributes */
|
||||
u_offset_t va_size; /* file size in bytes */
|
||||
} vattr_t;
|
||||
|
||||
#define AT_TYPE 0x0001
|
||||
#define AT_MODE 0x0002
|
||||
#define AT_UID 0x0004
|
||||
#define AT_GID 0x0008
|
||||
#define AT_FSID 0x0010
|
||||
#define AT_NODEID 0x0020
|
||||
#define AT_NLINK 0x0040
|
||||
#define AT_SIZE 0x0080
|
||||
#define AT_ATIME 0x0100
|
||||
#define AT_MTIME 0x0200
|
||||
#define AT_CTIME 0x0400
|
||||
#define AT_RDEV 0x0800
|
||||
#define AT_BLKSIZE 0x1000
|
||||
#define AT_NBLOCKS 0x2000
|
||||
#define AT_SEQ 0x8000
|
||||
|
||||
typedef struct xvattr {
|
||||
vattr_t xva_vattr; /* Embedded vattr structure */
|
||||
uint32_t xva_magic; /* Magic Number */
|
||||
uint32_t xva_mapsize; /* Size of attr bitmap (32-bit words) */
|
||||
uint32_t *xva_rtnattrmapp; /* Ptr to xva_rtnattrmap[] */
|
||||
uint32_t xva_reqattrmap[XVA_MAPSIZE]; /* Requested attrs */
|
||||
uint32_t xva_rtnattrmap[XVA_MAPSIZE]; /* Returned attrs */
|
||||
xoptattr_t xva_xoptattrs; /* Optional attributes */
|
||||
} xvattr_t;
|
||||
|
||||
typedef struct vsecattr {
|
||||
uint_t vsa_mask; /* See below */
|
||||
int vsa_aclcnt; /* ACL entry count */
|
||||
void *vsa_aclentp; /* pointer to ACL entries */
|
||||
int vsa_dfaclcnt; /* default ACL entry count */
|
||||
void *vsa_dfaclentp; /* pointer to default ACL entries */
|
||||
size_t vsa_aclentsz; /* ACE size in bytes of vsa_aclentp */
|
||||
} vsecattr_t;
|
||||
|
||||
#define AT_TYPE 0x00001
|
||||
#define AT_MODE 0x00002
|
||||
#define AT_UID 0x00004
|
||||
#define AT_GID 0x00008
|
||||
#define AT_FSID 0x00010
|
||||
#define AT_NODEID 0x00020
|
||||
#define AT_NLINK 0x00040
|
||||
#define AT_SIZE 0x00080
|
||||
#define AT_ATIME 0x00100
|
||||
#define AT_MTIME 0x00200
|
||||
#define AT_CTIME 0x00400
|
||||
#define AT_RDEV 0x00800
|
||||
#define AT_BLKSIZE 0x01000
|
||||
#define AT_NBLOCKS 0x02000
|
||||
#define AT_SEQ 0x08000
|
||||
#define AT_XVATTR 0x10000
|
||||
|
||||
#define CRCREAT 0
|
||||
|
||||
#define VOP_CLOSE(vp, f, c, o, cr) 0
|
||||
#define VOP_PUTPAGE(vp, of, sz, fl, cr) 0
|
||||
#define VOP_GETATTR(vp, vap, fl) ((vap)->va_size = (vp)->v_size, 0)
|
||||
#define VOP_CLOSE(vp, f, c, o, cr, ct) 0
|
||||
#define VOP_PUTPAGE(vp, of, sz, fl, cr, ct) 0
|
||||
#define VOP_GETATTR(vp, vap, cr) ((vap)->va_size = (vp)->v_size, 0)
|
||||
|
||||
#define VOP_FSYNC(vp, f, cr) fsync((vp)->v_fd)
|
||||
#define VOP_FSYNC(vp, f, cr, ct) fsync((vp)->v_fd)
|
||||
|
||||
#define VN_RELE(vp) vn_close(vp)
|
||||
#define VN_RELE(vp) vn_close(vp, 0, NULL, NULL)
|
||||
|
||||
#define vn_lock(vp, type)
|
||||
#define VOP_UNLOCK(vp, type)
|
||||
#ifdef VFS_LOCK_GIANT
|
||||
#undef VFS_LOCK_GIANT
|
||||
#endif
|
||||
#define VFS_LOCK_GIANT(mp) 0
|
||||
#ifdef VFS_UNLOCK_GIANT
|
||||
#undef VFS_UNLOCK_GIANT
|
||||
#endif
|
||||
#define VFS_UNLOCK_GIANT(vfslocked)
|
||||
|
||||
extern int vn_open(char *path, int x1, int oflags, int mode, vnode_t **vpp,
|
||||
int x2, int x3);
|
||||
extern int vn_openat(char *path, int x1, int oflags, int mode, vnode_t **vpp,
|
||||
int x2, int x3, vnode_t *vp);
|
||||
int x2, int x3, vnode_t *vp, int fd);
|
||||
extern int vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len,
|
||||
offset_t offset, int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp);
|
||||
extern void vn_close(vnode_t *vp);
|
||||
extern void vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td);
|
||||
|
||||
#define vn_remove(path, x1, x2) remove(path)
|
||||
#define vn_rename(from, to, seg) rename((from), (to))
|
||||
@ -397,8 +465,9 @@ extern void delay(clock_t ticks);
|
||||
|
||||
#define CPU_SEQID (thr_self() & (max_ncpus - 1))
|
||||
|
||||
#define kcred NULL
|
||||
#define CRED() NULL
|
||||
#ifndef ptob
|
||||
#define ptob(x) ((x) * PAGESIZE)
|
||||
#endif
|
||||
|
||||
extern uint64_t physmem;
|
||||
|
||||
@ -455,11 +524,31 @@ struct bootstat {
|
||||
uint64_t st_size;
|
||||
};
|
||||
|
||||
typedef struct ace_object {
|
||||
uid_t a_who;
|
||||
uint32_t a_access_mask;
|
||||
uint16_t a_flags;
|
||||
uint16_t a_type;
|
||||
uint8_t a_obj_type[16];
|
||||
uint8_t a_inherit_obj_type[16];
|
||||
} ace_object_t;
|
||||
|
||||
|
||||
#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05
|
||||
#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06
|
||||
#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07
|
||||
#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08
|
||||
|
||||
extern struct _buf *kobj_open_file(char *name);
|
||||
extern int kobj_read_file(struct _buf *file, char *buf, unsigned size,
|
||||
unsigned off);
|
||||
extern void kobj_close_file(struct _buf *file);
|
||||
extern int kobj_get_filesize(struct _buf *file, uint64_t *size);
|
||||
extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
|
||||
extern int zfs_secpolicy_rename_perms(const char *from, const char *to,
|
||||
cred_t *cr);
|
||||
extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
|
||||
extern zoneid_t getzoneid(void);
|
||||
/* Random compatibility stuff. */
|
||||
#define lbolt (gethrtime() >> 23)
|
||||
#define lbolt64 (gethrtime() >> 23)
|
||||
@ -482,18 +571,32 @@ struct file {
|
||||
#define FCREAT O_CREAT
|
||||
#define FOFFMAX 0x0
|
||||
|
||||
/* SID stuff */
|
||||
typedef struct ksiddomain {
|
||||
uint_t kd_ref;
|
||||
uint_t kd_len;
|
||||
char *kd_name;
|
||||
} ksiddomain_t;
|
||||
|
||||
ksiddomain_t *ksid_lookupdomain(const char *);
|
||||
void ksiddomain_rele(ksiddomain_t *);
|
||||
|
||||
#define SX_SYSINIT(name, lock, desc)
|
||||
|
||||
#define SYSCTL_DECL(...)
|
||||
#define SYSCTL_NODE(...)
|
||||
#define SYSCTL_INT(...)
|
||||
#define SYSCTL_UINT(...)
|
||||
#define SYSCTL_ULONG(...)
|
||||
#define SYSCTL_QUAD(...)
|
||||
#ifdef TUNABLE_INT
|
||||
#undef TUNABLE_INT
|
||||
#undef TUNABLE_ULONG
|
||||
#undef TUNABLE_QUAD
|
||||
#endif
|
||||
#define TUNABLE_INT(...)
|
||||
#define TUNABLE_ULONG(...)
|
||||
#define TUNABLE_QUAD(...)
|
||||
|
||||
/* Errors */
|
||||
|
||||
|
@ -2,9 +2,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* 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.
|
||||
@ -20,7 +19,7 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -177,6 +176,9 @@ taskq_create(const char *name, int nthreads, pri_t pri,
|
||||
int t;
|
||||
|
||||
rw_init(&tq->tq_threadlock, NULL, RW_DEFAULT, NULL);
|
||||
mutex_init(&tq->tq_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL);
|
||||
cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL);
|
||||
tq->tq_flags = flags | TASKQ_ACTIVE;
|
||||
tq->tq_active = nthreads;
|
||||
tq->tq_nthreads = nthreads;
|
||||
@ -230,6 +232,9 @@ taskq_destroy(taskq_t *tq)
|
||||
kmem_free(tq->tq_threadlist, nthreads * sizeof (thread_t));
|
||||
|
||||
rw_destroy(&tq->tq_threadlock);
|
||||
mutex_destroy(&tq->tq_lock);
|
||||
cv_destroy(&tq->tq_dispatch_cv);
|
||||
cv_destroy(&tq->tq_wait_cv);
|
||||
|
||||
kmem_free(tq, sizeof (taskq_t));
|
||||
}
|
||||
|
@ -19,12 +19,10 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/avl.h>
|
||||
@ -67,46 +65,58 @@ nicenum(uint64_t num, char *buf)
|
||||
}
|
||||
|
||||
static void
|
||||
show_vdev_stats(const char *desc, nvlist_t *nv, int indent)
|
||||
show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent)
|
||||
{
|
||||
vdev_stat_t *vs;
|
||||
vdev_stat_t v0 = { 0 };
|
||||
uint64_t sec;
|
||||
uint64_t is_log = 0;
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
vdev_stat_t *vs;
|
||||
uint64_t sec;
|
||||
char used[6], avail[6];
|
||||
char rops[6], wops[6], rbytes[6], wbytes[6], rerr[6], werr[6], cerr[6];
|
||||
char *prefix = "";
|
||||
|
||||
if (indent == 0) {
|
||||
(void) printf(" "
|
||||
if (indent == 0 && desc != NULL) {
|
||||
(void) printf(" "
|
||||
" capacity operations bandwidth ---- errors ----\n");
|
||||
(void) printf("description "
|
||||
(void) printf("description "
|
||||
"used avail read write read write read write cksum\n");
|
||||
}
|
||||
|
||||
VERIFY(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
|
||||
(uint64_t **)&vs, &c) == 0);
|
||||
if (desc != NULL) {
|
||||
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
|
||||
|
||||
sec = MAX(1, vs->vs_timestamp / NANOSEC);
|
||||
if (is_log)
|
||||
prefix = "log ";
|
||||
|
||||
nicenum(vs->vs_alloc, used);
|
||||
nicenum(vs->vs_space - vs->vs_alloc, avail);
|
||||
nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops);
|
||||
nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops);
|
||||
nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes);
|
||||
nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes);
|
||||
nicenum(vs->vs_read_errors, rerr);
|
||||
nicenum(vs->vs_write_errors, werr);
|
||||
nicenum(vs->vs_checksum_errors, cerr);
|
||||
if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
|
||||
(uint64_t **)&vs, &c) != 0)
|
||||
vs = &v0;
|
||||
|
||||
(void) printf("%*s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n",
|
||||
indent, "",
|
||||
indent - 19 - (vs->vs_space ? 0 : 12), desc,
|
||||
vs->vs_space ? 6 : 0, vs->vs_space ? used : "",
|
||||
vs->vs_space ? 6 : 0, vs->vs_space ? avail : "",
|
||||
rops, wops, rbytes, wbytes, rerr, werr, cerr);
|
||||
sec = MAX(1, vs->vs_timestamp / NANOSEC);
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
|
||||
&child, &children) != 0)
|
||||
nicenum(vs->vs_alloc, used);
|
||||
nicenum(vs->vs_space - vs->vs_alloc, avail);
|
||||
nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops);
|
||||
nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops);
|
||||
nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes);
|
||||
nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes);
|
||||
nicenum(vs->vs_read_errors, rerr);
|
||||
nicenum(vs->vs_write_errors, werr);
|
||||
nicenum(vs->vs_checksum_errors, cerr);
|
||||
|
||||
(void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n",
|
||||
indent, "",
|
||||
prefix,
|
||||
indent + strlen(prefix) - 25 - (vs->vs_space ? 0 : 12),
|
||||
desc,
|
||||
vs->vs_space ? 6 : 0, vs->vs_space ? used : "",
|
||||
vs->vs_space ? 6 : 0, vs->vs_space ? avail : "",
|
||||
rops, wops, rbytes, wbytes, rerr, werr, cerr);
|
||||
}
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nv, ctype, &child, &children) != 0)
|
||||
return;
|
||||
|
||||
for (c = 0; c < children; c++) {
|
||||
@ -120,7 +130,7 @@ show_vdev_stats(const char *desc, nvlist_t *nv, int indent)
|
||||
(void) strcpy(tname, cname);
|
||||
if (nvlist_lookup_uint64(cnv, ZPOOL_CONFIG_NPARITY, &np) == 0)
|
||||
tname[strlen(tname)] = '0' + np;
|
||||
show_vdev_stats(tname, cnv, indent + 2);
|
||||
show_vdev_stats(tname, ctype, cnv, indent + 2);
|
||||
free(tname);
|
||||
}
|
||||
}
|
||||
@ -131,14 +141,16 @@ show_pool_stats(spa_t *spa)
|
||||
nvlist_t *config, *nvroot;
|
||||
char *name;
|
||||
|
||||
spa_config_enter(spa, RW_READER, FTAG);
|
||||
config = spa_config_generate(spa, NULL, -1ULL, B_TRUE);
|
||||
spa_config_exit(spa, FTAG);
|
||||
VERIFY(spa_get_stats(spa_name(spa), &config, NULL, 0) == 0);
|
||||
|
||||
VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
||||
&nvroot) == 0);
|
||||
VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
|
||||
&name) == 0);
|
||||
|
||||
show_vdev_stats(name, nvroot, 0);
|
||||
show_vdev_stats(name, ZPOOL_CONFIG_CHILDREN, nvroot, 0);
|
||||
show_vdev_stats(NULL, ZPOOL_CONFIG_L2CACHE, nvroot, 0);
|
||||
show_vdev_stats(NULL, ZPOOL_CONFIG_SPARES, nvroot, 0);
|
||||
|
||||
nvlist_free(config);
|
||||
}
|
||||
|
@ -10,14 +10,17 @@ DPADD= ${LIBUTIL}
|
||||
LDADD= -lutil
|
||||
|
||||
SRCS= deviceid.c \
|
||||
mnttab.c \
|
||||
mkdirp.c \
|
||||
zmount.c \
|
||||
fsshare.c \
|
||||
mkdirp.c \
|
||||
mnttab.c \
|
||||
zmount.c \
|
||||
zone.c
|
||||
|
||||
SRCS+= zfs_namecheck.c \
|
||||
SRCS+= zfs_deleg.c \
|
||||
zfs_namecheck.c \
|
||||
zfs_prop.c \
|
||||
zpool_prop.c \
|
||||
zprop_common.c \
|
||||
libzfs_dataset.c \
|
||||
libzfs_util.c \
|
||||
libzfs_graph.c \
|
||||
@ -26,6 +29,7 @@ SRCS+= zfs_namecheck.c \
|
||||
libzfs_changelist.c \
|
||||
libzfs_config.c \
|
||||
libzfs_import.c \
|
||||
libzfs_sendrecv.c \
|
||||
libzfs_status.c
|
||||
|
||||
CFLAGS+= -DZFS_NO_ACL
|
||||
|
@ -18,6 +18,8 @@ ATOMIC_SRCS= atomic.S
|
||||
.PATH: ${.CURDIR}/../../../sys/cddl/compat/opensolaris/kern
|
||||
ATOMIC_SRCS= opensolaris_atomic.c
|
||||
.endif
|
||||
# UNICODE_SRCS
|
||||
.PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/unicode
|
||||
|
||||
LIB= zpool
|
||||
|
||||
@ -25,9 +27,13 @@ ZFS_COMMON_SRCS= ${ZFS_COMMON_OBJS:C/.o$/.c/} vdev_file.c
|
||||
ZFS_SHARED_SRCS= ${ZFS_SHARED_OBJS:C/.o$/.c/}
|
||||
KERNEL_SRCS= kernel.c taskq.c util.c
|
||||
LIST_SRCS= list.c
|
||||
UNICODE_SRCS= u8_textprep.c
|
||||
|
||||
SRCS= ${ZFS_COMMON_SRCS} ${ZFS_SHARED_SRCS} \
|
||||
${KERNEL_SRCS} ${LIST_SRCS} ${ATOMIC_SRCS}
|
||||
${KERNEL_SRCS} ${LIST_SRCS} ${ATOMIC_SRCS} \
|
||||
${UNICODE_SRCS}
|
||||
|
||||
CFLAGS+= -std=c99
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
|
||||
@ -40,6 +46,13 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/lib/libumem
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
|
||||
# XXX: pthread doesn't have mutex_owned() equivalent, so we need to look
|
||||
# into libthr private structures. That's sooo evil, but it's only for
|
||||
# ZFS debugging tools needs.
|
||||
CFLAGS+= -DWANTS_MUTEX_OWNED
|
||||
CFLAGS+= -I${.CURDIR}/../../../lib/libpthread/thread
|
||||
CFLAGS+= -I${.CURDIR}/../../../lib/libpthread/sys
|
||||
CFLAGS+= -I${.CURDIR}/../../../lib/libthr/arch/${MACHINE_ARCH}/include
|
||||
|
||||
DPADD= ${LIBPTHREAD} ${LIBZ}
|
||||
LDADD= -lpthread -lz
|
||||
|
@ -1,10 +1,11 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/zpool
|
||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/zpool \
|
||||
${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
|
||||
|
||||
PROG= zpool
|
||||
MAN= zpool.8
|
||||
SRCS= zpool_main.c zpool_vdev.c zpool_iter.c zpool_util.c
|
||||
SRCS= zpool_main.c zpool_vdev.c zpool_iter.c zpool_util.c zfs_comutil.c
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
|
||||
@ -15,6 +16,7 @@ CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libuutil/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libumem/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
|
||||
|
@ -7,9 +7,11 @@ SUBDIR= \
|
||||
ctfdump \
|
||||
ctfmerge \
|
||||
sgsmsg \
|
||||
${_zinject} \
|
||||
${_ztest}
|
||||
|
||||
.if ${MK_ZFS} != "no"
|
||||
_zinject= zinject
|
||||
.if ${MK_LIBTHR} != "no"
|
||||
_ztest= ztest
|
||||
.endif
|
||||
|
25
cddl/usr.bin/zinject/Makefile
Normal file
25
cddl/usr.bin/zinject/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../contrib/opensolaris/cmd/zinject
|
||||
|
||||
PROG= zinject
|
||||
SRCS= zinject.c translate.c
|
||||
NO_MAN=
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
|
||||
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/include
|
||||
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/lib/libumem
|
||||
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libzfs/common
|
||||
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libzpool/common
|
||||
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libnvpair
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
|
||||
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
|
||||
CFLAGS+= -I${.CURDIR}/../../lib/libumem
|
||||
|
||||
DPADD= ${LIBAVL} ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBUUTIL} \
|
||||
${LIBZFS} ${LIBZPOOL} ${LIBUUTIL}
|
||||
LDADD= -lavl -lgeom -lm -lnvpair -lumem -luutil -lzfs -lzpool
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,18 +1,20 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/ztest
|
||||
.PATH: ${.CURDIR}/../..//contrib/opensolaris/cmd/ztest
|
||||
|
||||
PROG= ztest
|
||||
NO_MAN=
|
||||
|
||||
CFLAGS+= -std=c99
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
|
||||
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/include
|
||||
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/lib/libumem
|
||||
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libzpool/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
|
||||
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
|
||||
CFLAGS+= -I${.CURDIR}/../../lib/libumem
|
||||
|
||||
DPADD= ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBZPOOL} \
|
||||
|
@ -6,9 +6,14 @@ PROG= zdb
|
||||
MAN= zdb.8
|
||||
SRCS= zdb.c zdb_il.c
|
||||
|
||||
CFLAGS+= -std=c99
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libuutil/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
|
||||
@ -16,8 +21,8 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
|
||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
|
||||
CFLAGS+= -I${.CURDIR}/../../lib/libumem
|
||||
|
||||
DPADD= ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBZPOOL} \
|
||||
${LIBPTHREAD} ${LIBZ} ${LIBAVL}
|
||||
LDADD= -lm -lnvpair -lumem -lzpool -lpthread -lz -lavl
|
||||
DPADD= ${LIBAVL} ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBPTHREAD} ${LIBUMEM} \
|
||||
${LIBUUTIL} ${LIBZ} ${LIBZFS} ${LIBZPOOL}
|
||||
LDADD= -lavl -lgeom -lm -lnvpair -lpthread -lumem -luutil -lz -lzfs -lzpool
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -181,20 +181,6 @@ struct arm_prologue_cache
|
||||
|
||||
int arm_apcs_32 = 1;
|
||||
|
||||
/* Flag set by arm_fix_call_dummy that tells whether the target
|
||||
function is a Thumb function. This flag is checked by
|
||||
arm_push_arguments. FIXME: Change the PUSH_ARGUMENTS macro (and
|
||||
its use in valops.c) to pass the function address as an additional
|
||||
parameter. */
|
||||
|
||||
static int target_is_thumb;
|
||||
|
||||
/* Flag set by arm_fix_call_dummy that tells whether the calling
|
||||
function is a Thumb function. This flag is checked by
|
||||
arm_pc_is_thumb and arm_call_dummy_breakpoint_offset. */
|
||||
|
||||
static int caller_is_thumb;
|
||||
|
||||
/* Determine if the program counter specified in MEMADDR is in a Thumb
|
||||
function. */
|
||||
|
||||
@ -219,27 +205,6 @@ arm_pc_is_thumb (CORE_ADDR memaddr)
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if the program counter specified in MEMADDR is in a call
|
||||
dummy being called from a Thumb function. */
|
||||
|
||||
int
|
||||
arm_pc_is_thumb_dummy (CORE_ADDR memaddr)
|
||||
{
|
||||
CORE_ADDR sp = read_sp ();
|
||||
|
||||
/* FIXME: Until we switch for the new call dummy macros, this heuristic
|
||||
is the best we can do. We are trying to determine if the pc is on
|
||||
the stack, which (hopefully) will only happen in a call dummy.
|
||||
We hope the current stack pointer is not so far alway from the dummy
|
||||
frame location (true if we have not pushed large data structures or
|
||||
gone too many levels deep) and that our 1024 is not enough to consider
|
||||
code regions as part of the stack (true for most practical purposes). */
|
||||
if (DEPRECATED_PC_IN_CALL_DUMMY (memaddr, sp, sp + 1024))
|
||||
return caller_is_thumb;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove useless bits from addresses in a running program. */
|
||||
static CORE_ADDR
|
||||
arm_addr_bits_remove (CORE_ADDR val)
|
||||
@ -2021,7 +1986,7 @@ arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
|
||||
|
||||
if (arm_pc_is_thumb (*pcptr) || arm_pc_is_thumb_dummy (*pcptr))
|
||||
if (arm_pc_is_thumb (*pcptr))
|
||||
{
|
||||
*pcptr = UNMAKE_THUMB_ADDR (*pcptr);
|
||||
*lenptr = tdep->thumb_breakpoint_size;
|
||||
|
@ -1,4 +1,4 @@
|
||||
Announcing ncurses 5.6
|
||||
Announcing ncurses 5.7
|
||||
|
||||
The ncurses (new curses) library is a free software emulation of
|
||||
curses in System V Release 4.0, and more. It uses terminfo format,
|
||||
@ -27,205 +27,217 @@
|
||||
Release Notes
|
||||
|
||||
This release is designed to be upward compatible from ncurses 5.0
|
||||
through 5.5; very few applications will require recompilation,
|
||||
through 5.6; very few applications will require recompilation,
|
||||
depending on the platform. These are the highlights from the
|
||||
change-log since ncurses 5.5 release.
|
||||
change-log since ncurses 5.6 release.
|
||||
|
||||
Interface changes:
|
||||
* generate linkable stubs for some macros:
|
||||
getbegx, getbegy, getcurx, getcury, getmaxx, getmaxy, getparx,
|
||||
getpary, getpary,
|
||||
and (for libncursesw)
|
||||
wgetbkgrnd
|
||||
getattrs
|
||||
|
||||
New features and improvements:
|
||||
* library
|
||||
+ support hashed databases for the terminal descriptions. This
|
||||
uses the Berkeley database, has been tested for several
|
||||
versions on different platforms.
|
||||
+ add use_legacy_coding() function to support lynx's
|
||||
font-switching feature.
|
||||
+ add extension nofilter(), to cancel a prior filter() call.
|
||||
+ add/install a package config script, e.g., ncurses5-config or
|
||||
ncursesw5-config, according to configuration options.
|
||||
+ provide ifdef for NCURSES_NOMACROS which suppresses most
|
||||
macro definitions from curses.h, i.e., where a macro is
|
||||
defined to override a function to improve performance.
|
||||
+ make ifdef's consistent in curses.h for the extended colors
|
||||
so the header file can be used for the normal curses library.
|
||||
The header file installed for extended colors is a variation
|
||||
of the wide-character configuration.
|
||||
+ improve tgetstr() by making the return value point into the
|
||||
user's buffer, if provided.
|
||||
+ add ifdef's allowing ncurses to be built with tparm() using
|
||||
either varargs (the existing status), or using a
|
||||
fixed-parameter list (to match X/Open).
|
||||
+ widen the test for xterm kmous a little to allow for other
|
||||
strings than "\E[M", e.g., for xterm-sco functionality in
|
||||
xterm.
|
||||
+ modify wgetnstr() to return KEY_RESIZE if a sigwinch occurs.
|
||||
+ move prototypes for wide-character trace functions from
|
||||
curses.tail to curses.wide to avoid accidental reference to
|
||||
those if _XOPEN_SOURCE_EXTENDED is defined without ensuring
|
||||
that <wchar.h> is included.
|
||||
+ change the way shared libraries (other than libtool) are
|
||||
installed. Rather than copying the build-tree's libraries,
|
||||
link the shared objects into the install directory. This
|
||||
makes the --with-rpath option work except with $(DESTDIR).
|
||||
+ several improvements for rendering in hpterm. These are only
|
||||
available if the library is configured using
|
||||
--enable-xmc-glitch.
|
||||
+ Add NCURSES_NO_HARD_TABS and NCURSES_NO_MAGIC_COOKIE
|
||||
environment variables to allow runtime suppression of the
|
||||
related hard-tabs and xmc-glitch features.
|
||||
+ new flavor of the ncurses library provides rudimentary
|
||||
support for POSIX threads. Several functions are reentrant,
|
||||
but most require either a window-level or screen-level mutex.
|
||||
(This is API-compatible, but not ABI-compatible with the
|
||||
normal library).
|
||||
+ add NCURSES_OPAQUE symbol to curses.h, will use to make
|
||||
structs opaque in selected configurations.
|
||||
+ add NCURSES_EXT_FUNCS and NCURSES_EXT_COLORS symbols to
|
||||
curses.h to make it simpler to tell if the extended functions
|
||||
and/or colors are declared.
|
||||
+ add wresize() to C++ binding
|
||||
+ eliminate fixed-buffer vsprintf() calls in C++ binding.
|
||||
+ add several functions to C++ binding which wrap C functions
|
||||
that pass a WINDOW* parameter.
|
||||
+ adapt mouse-handling code from menu library in form-library
|
||||
+ improve tracing for form library, showing created forms,
|
||||
fields, etc.
|
||||
+ make $NCURSES_NO_PADDING feature work for termcap interface .
|
||||
+ add check to trace-file open, if the given name is a
|
||||
directory, add ".log" to the name and try again.
|
||||
+ several new manpages: curs_legacy.3x, curs_memleaks.3x,
|
||||
curs_opaque.3x and curs_threads.3x
|
||||
* programs:
|
||||
+ add new test programs: chgat.c, demo_altkeys.c, echochar.c,
|
||||
foldkeys.c, movewindow.c, redraw.c, (noting that existing
|
||||
test programs also were modified to test additional
|
||||
features).
|
||||
+ modify tack to test extended capability function-key strings.
|
||||
+ modify toe to access termcap data, e.g., via cgetent()
|
||||
functions, or as a text file if those are not available.
|
||||
+ improve infocmp/tic -f option formatting.
|
||||
+ add toe -a option, to show all databases. This uses new
|
||||
private interfaces in the ncurses library for iterating
|
||||
through the list of databases.
|
||||
+ modify MKfallback.sh to use tic -x when constructing fallback
|
||||
tables to allow extended capabilities to be retrieved from a
|
||||
fallback entry.
|
||||
+ modified three test-programs to demonstrate the threading
|
||||
support in this version: ditto, rain, worm.
|
||||
+ several new test-programs: demo_panels, dots_mvcur,
|
||||
inch_wide, inchs, key_name, key_names, savescreen,
|
||||
savescreen.sh test_arrays, test_get_wstr, test_getstr,
|
||||
test_instr, test_inwstr and test_opaque.
|
||||
+ add adacurses-config to the Ada95 install.
|
||||
+ modify tic -f option to format spaces as \s to prevent them
|
||||
from being lost when that is read back in unformatted
|
||||
strings.
|
||||
+ The tack program is now distributed separately from ncurses.
|
||||
* terminal database
|
||||
+ add terminfo entries for xfce terminal (xfce) and multi gnome
|
||||
terminal (mgt)
|
||||
+ add nsterm-16color entry
|
||||
+ updated mlterm terminfo entry
|
||||
+ add kon, kon2 and jfbterm terminfo entry
|
||||
+ remove invis capability from klone+sgr, mainly used by linux
|
||||
entry, since it does not really do this
|
||||
+ add ka2, kb1, kb3, kc2 to vt220-keypad as an extension
|
||||
+ add shifted up/down arrow codes to xterm-new as kind/kri
|
||||
strings
|
||||
+ add hpterm-color terminfo entry
|
||||
+ add 256color variants of terminfo entries for programs which
|
||||
are reported to implement this feature
|
||||
+ correct order of use-clauses in rxvt-basic entry which made
|
||||
codes for f1-f4 vt100-style rather than vt220-style.
|
||||
+ added entries:
|
||||
o Eterm-256color, Eterm-88color and rxvt-88color
|
||||
o aterm
|
||||
o konsole-256color
|
||||
o mrxvt
|
||||
o screen.mlterm
|
||||
o screen.rxvt
|
||||
o teraterm4.59 is now the primary primary teraterm entry,
|
||||
renamed original to teraterm2.3
|
||||
o 9term terminal
|
||||
o Newbury Data entries
|
||||
+ updated/improved entries:
|
||||
o gnome to version 2.22.3
|
||||
o h19, z100
|
||||
o konsole to version 1.6.6
|
||||
o mlterm, mlterm+pcfkeys
|
||||
o xterm, and building-blocks for function-keys to [3]xterm
|
||||
patch #230.
|
||||
|
||||
Major bug fixes:
|
||||
* correct a typo in configure --with-bool option for the case where
|
||||
--without-cxx is used.
|
||||
* move assignment from environment variable ESCDELAY from initscr()
|
||||
down to newterm() so the environment variable affects timeouts for
|
||||
terminals opened with newterm() as well.
|
||||
* modify werase to clear multicolumn characters that extend into a
|
||||
derived window.
|
||||
* modify wchgat() to mark updated cells as changed so a refresh will
|
||||
repaint those cells.
|
||||
* correct logic in wadd_wch() and wecho_wch(), which did not guard
|
||||
against passing the multi-column attribute into a call on
|
||||
waddch(), e.g., using data returned by win_wch()
|
||||
* fix redrawing of windows other than stdscr using wredrawln() by
|
||||
touching the corresponding rows in curscr.
|
||||
* reduce memory leaks in repeated calls to tgetent() by remembering
|
||||
the last TERMINAL* value allocated to hold the corresponding data
|
||||
and freeing that if the tgetent() result buffer is the same as the
|
||||
previous call.
|
||||
* modify read_termtype() so the term_names data is always allocated
|
||||
as part of the str_table, a better fix for a memory leak.
|
||||
* fix wins_nwstr(), which did not handle single-column non-8bit
|
||||
codes.
|
||||
* modify wbkgrnd() to avoid clearing the A_CHARTEXT attribute bits
|
||||
since those record the state of multicolumn characters.
|
||||
* improve SIGWINCH handling by postponing its effect during
|
||||
newterm(), etc., when allocating screens.
|
||||
* remove 970913 feature for copying subwindows as they are moved in
|
||||
mvwin().
|
||||
* add checks in waddchnstr() and wadd_wchnstr() to stop copying when
|
||||
a null character is found.
|
||||
* add some checks to ensure current position is within scrolling
|
||||
region before scrolling on a new line.
|
||||
* add a workaround to ACS mapping to allow applications such as
|
||||
test/blue.c to use the "PC ROM" characters by masking them with
|
||||
A_ALTCHARSET. This worked up til 5.5, but was lost in the revision
|
||||
of legacy coding.
|
||||
* add logic to tic for cancelling strings in user-defined
|
||||
capabilities (this is needed for current konsole terminfo entry).
|
||||
* modify mk-1st.awk so the generated makefile rules for linking or
|
||||
installing shared libraries do not first remove the library, in
|
||||
case it is in use, e.g., libncurses.so by /bin/sh.
|
||||
* correct check for notimeout() in wgetch().
|
||||
* fix a sign-extension bug in infocmp's repair_acsc() function.
|
||||
* change winnstr() to stop at the end of the line.
|
||||
* make Ada95 demo_panels() example work.
|
||||
* fix for adding a non-spacing character at the beginning of a line.
|
||||
* fill in extended-color pair to make colors work for
|
||||
wide-characters using extended-colors.
|
||||
* improve refresh of window on top of multi-column characters,
|
||||
taking into account split characters on left/right window
|
||||
boundaries.
|
||||
* modify win_wchnstr() to ensure that only a base cell is returned
|
||||
for each multi-column character.
|
||||
* improve waddch() and winsch() handling of EILSEQ from mbrtowc() by
|
||||
using unctrl() to display illegal bytes rather than trying to
|
||||
append further bytes to make up a valid sequence.
|
||||
* restore curs_set() state after endwin()/refresh()
|
||||
* modify keyname() to use "^X" form only if meta() has been called,
|
||||
or if keyname() is called without initializing curses, e.g., via
|
||||
initscr() or newterm().
|
||||
* modify unctrl() to check codes in 128-255 range versus isprint().
|
||||
If they are not printable, and locale was set, use a "M-" or "~"
|
||||
sequence.
|
||||
* improve resizeterm() by moving ripped-off lines, and repainting
|
||||
the soft-keys.
|
||||
* modify form library to accept control characters such as newline
|
||||
in set_field_buffer(), which is compatible with Solaris.
|
||||
* use NCURSES_MOUSE_MASK() in definition of BUTTON_RELEASE(), etc.,
|
||||
to make those work properly with the --enable-ext-mouse
|
||||
configuration
|
||||
* correct some functions in Ada95 binding which were using return
|
||||
value from C where none was returned.
|
||||
* reviewed/fixed issues reported by Coverity and Klocwork tools.
|
||||
|
||||
Portability:
|
||||
* configure script:
|
||||
+ new options:
|
||||
|
||||
--with-hashed-db
|
||||
Use Berkeley hashed database for storing terminfo
|
||||
data rather than storing each compiled entry in a
|
||||
separate binary file within a directory tree.
|
||||
--disable-big-strings
|
||||
control whether static string tables are generated
|
||||
as single large strings (to improve startup
|
||||
performance), or as array of individual strings.
|
||||
|
||||
--without-dlsym
|
||||
Do not use dlsym() to load GPM dynamically.
|
||||
--disable-relink
|
||||
control whether shared libraries are relinked
|
||||
(during install) when rpath is enabled.
|
||||
|
||||
--with-valgrind
|
||||
Simplify building for testing with valgrind.
|
||||
--disable-tic-depends
|
||||
make explicit whether tic library depends on
|
||||
ncurses/ncursesw library.
|
||||
|
||||
--enable-wgetch-events
|
||||
Compile with experimental wgetch-events code.
|
||||
--enable-mixed-case
|
||||
override the configure script's check if the
|
||||
filesystem supports mixed-case filenames. This
|
||||
allows one to control how the terminal database
|
||||
maps to the filesystem. For filesystems that do not
|
||||
support mixed-case, the library uses generate
|
||||
2-character (hexadecimal) codes for the lower-level
|
||||
of the filesystem terminfo database
|
||||
|
||||
--enable-signed-char
|
||||
Store booleans in "signed char" rather than "char".
|
||||
--enable-reentrant
|
||||
builds a different flavor of the ncurses library
|
||||
(ncursest) which improves reentrant use of the
|
||||
library by reducing global and static variables
|
||||
(see the "--with-pthread" option for the threaded
|
||||
support).
|
||||
|
||||
--enable-weak-symbols
|
||||
use weak-symbols for linking to the POSIX thread
|
||||
library, and use the same soname for the ncurses
|
||||
shared library as the normal library (caveat: the
|
||||
ABI is for the threaded library, which makes global
|
||||
data accessed via functions).
|
||||
|
||||
--with-pthread
|
||||
build with the POSIX thread library (tested with
|
||||
AIX, Linux, FreeBSD, OpenBSD, HPUX, IRIX64,
|
||||
Solaris, Tru64).
|
||||
|
||||
--with-ticlib
|
||||
build/install the tic-support functions in a
|
||||
separate library
|
||||
|
||||
+ improved options:
|
||||
|
||||
--disable-largefile
|
||||
make the option work both ways.
|
||||
--enable-ext-colors
|
||||
requires the wide-character configuration.
|
||||
|
||||
--with-gpm
|
||||
The option now accepts a parameter, i.e., the name
|
||||
of the dynamic GPM library to load via dlopen()
|
||||
--with-chtype
|
||||
ignore option value "unsigned" is always added to
|
||||
the type in curses.h; do the same for
|
||||
--with-mmask-t.
|
||||
|
||||
--disable-symlinks
|
||||
The option now allows one to disable symlink() in
|
||||
tic even when link() does not work.
|
||||
--with-dmalloc
|
||||
build-fix for redefinition of strndup.
|
||||
|
||||
--with-hashed-db
|
||||
accepts a parameter which is the install-prefix of
|
||||
a given Berkeley Database.
|
||||
|
||||
--with-hashed-db
|
||||
the $LIBS environment variable overrides the search
|
||||
for the db library.
|
||||
|
||||
--without-hashed-db
|
||||
assumed when "--disable-database" is used.
|
||||
|
||||
* other configure/build issues:
|
||||
+ remove special case for Darwin in CF_XOPEN_SOURCE configure
|
||||
macro.
|
||||
+ add configure check to ensure that SIGWINCH is defined on
|
||||
platforms such as OS X which exclude that when _XOPEN_SOURCE,
|
||||
etc., are defined
|
||||
+ use ld's -search_paths_first option on Darwin to work around
|
||||
odd search rules on that platform.
|
||||
+ improve ifdef's for _POSIX_VDISABLE in tset to work with Mac
|
||||
OS X.
|
||||
+ modify configure script to ensure that if the C compiler is
|
||||
used rather than the loader in making shared libraries, the
|
||||
$(CFLAGS) variable is also used.
|
||||
+ use ${CC} rather than ${LD} in shared library rules for
|
||||
IRIX64, Solaris to help ensure that initialization sections
|
||||
are provided for extra linkage requirements, e.g., of C++
|
||||
applications.
|
||||
+ improve some shared-library configure scripting for Linux,
|
||||
FreeBSD and NetBSD to make --with-shlib-version work.
|
||||
+ split up dependency of names.c and codes.c in
|
||||
ncurses/Makefile to work with parallel make.
|
||||
+ modify MKlib_gen.sh to change preprocessor-expanded _Bool
|
||||
back to bool.
|
||||
+ modify progs/Makefile.in to make tput init work properly with
|
||||
cygwin, i.e., do not pass a .exe in the reference string used
|
||||
in check_aliases.
|
||||
+ build-fixes for LynxOS
|
||||
+ modify shared-library rules to allow FreeBSD 3.x to use
|
||||
rpath.
|
||||
+ build-fix for FreeBSD "contemporary" TTY interface.
|
||||
+ build-fixes for AIX with libtool.
|
||||
+ build-fixes for Darwin and libtool.
|
||||
+ modify BeOS-specific ifdef's to build on Haiku.
|
||||
+ corrected gcc options for building shared libraries on
|
||||
Solaris and IRIX64.
|
||||
+ change shared-library configuration for OpenBSD, make rpath
|
||||
work.
|
||||
+ build-fixes for using libutf8, e.g., on OpenBSD 3.7
|
||||
+ add "-e" option in ncurses/Makefile.in when generating
|
||||
source-files to force earlier exit if the build environment
|
||||
fails unexpectedly.
|
||||
+ add support for shared libraries for QNX.
|
||||
+ change delimiter in MKlib_gen.sh from '%' to '@', to avoid
|
||||
substitution by IBM xlc to '#' as part of its extensions to
|
||||
digraphs.
|
||||
* library:
|
||||
+ ignore wide-acs line-drawing characters that wcwidth() claims
|
||||
are not one-column. This is a workaround for Solaris' broken
|
||||
locale support.
|
||||
+ reduce name-pollution in term.h by removing #define's for
|
||||
HAVE_xxx symbols.
|
||||
+ fix #ifdef in c++/internal.h for QNX 6.1
|
||||
+ rewrite wrapper for wcrtomb(), making it work on Solaris.
|
||||
This is used in the form library to determine the length of
|
||||
the buffer needed by field_buffer.
|
||||
+ add/use configure script macro CF_SIG_ATOMIC_T, use the
|
||||
corresponding type for data manipulated by signal handlers.
|
||||
+ set locale in misc/ncurses-config.in since it uses a range
|
||||
+ disable GPM mouse support when $TERM does not happen to
|
||||
contain "linux", since Gpm_Open() no longer limits its
|
||||
assertion to terminals that it might handle, e.g., within
|
||||
"screen" in xterm.
|
||||
+ reset mouse file-descriptor when unloading GPM library.
|
||||
* test programs:
|
||||
+ modify test/configure script to allow building test programs
|
||||
with PDCurses/X11.
|
||||
+ modified test programs to allow some to work with NetBSD
|
||||
curses. Several do not because NetBSD curses implements a
|
||||
subset of X/Open curses, and also lacks much of SVr4
|
||||
additions. But it is enough for comparison.
|
||||
+ improved test/configure to build test/ncurses on HPUX 11
|
||||
using the vendor curses.
|
||||
+ change configure script to produce test/Makefile from data
|
||||
file.
|
||||
+ update test programs to build/work with various UNIX curses
|
||||
for comparisons.
|
||||
|
||||
Features of Ncurses
|
||||
|
||||
@ -271,6 +283,8 @@
|
||||
the use of function keys, e.g., disabling the ncurses KEY_MOUSE,
|
||||
or by defining more than one control sequence to map to a given
|
||||
key code.
|
||||
* Support for 256-color terminals, such as modern xterm, when
|
||||
configured using the --enable-ext-colors option.
|
||||
* Support for 16-color terminals, such as aixterm and modern xterm.
|
||||
* Better cursor-movement optimization. The package now features a
|
||||
cursor-local-movement computation more efficient than either BSD's
|
||||
@ -342,49 +356,45 @@
|
||||
|
||||
cdk
|
||||
Curses Development Kit
|
||||
[3]http://invisible-island.net/cdk/
|
||||
[4]http://www.vexus.ca/products/CDK/
|
||||
[4]http://invisible-island.net/cdk/
|
||||
[5]http://www.vexus.ca/products/CDK/
|
||||
|
||||
ded
|
||||
directory-editor
|
||||
[5]http://invisible-island.net/ded/
|
||||
[6]http://invisible-island.net/ded/
|
||||
|
||||
dialog
|
||||
the underlying application used in Slackware's setup, and the
|
||||
basis for similar applications on GNU/Linux.
|
||||
[6]http://invisible-island.net/dialog/
|
||||
[7]http://invisible-island.net/dialog/
|
||||
|
||||
lynx
|
||||
the character-screen WWW browser
|
||||
[7]http://lynx.isc.org/release/
|
||||
[8]http://lynx.isc.org/release/
|
||||
|
||||
Midnight Commander
|
||||
file manager
|
||||
[8]http://www.ibiblio.org/mc/
|
||||
[9]http://www.ibiblio.org/mc/
|
||||
|
||||
mutt
|
||||
mail utility
|
||||
[9]http://www.mutt.org/
|
||||
[10]http://www.mutt.org/
|
||||
|
||||
ncftp
|
||||
file-transfer utility
|
||||
[10]http://www.ncftp.com/
|
||||
[11]http://www.ncftp.com/
|
||||
|
||||
nvi
|
||||
New vi versions 1.50 are able to use ncurses versions 1.9.7 and
|
||||
later.
|
||||
[11]http://www.bostic.com/vi/
|
||||
[12]http://www.bostic.com/vi/
|
||||
|
||||
pinfo
|
||||
Lynx-like info browser.
|
||||
[12]http://dione.ids.pl/~pborys/software/pinfo/
|
||||
[13]https://alioth.debian.org/projects/pinfo/
|
||||
|
||||
tin
|
||||
newsreader, supporting color, MIME [13]http://www.tin.org/
|
||||
|
||||
vh-1.6
|
||||
Volks-Hypertext browser for the Jargon File
|
||||
[14]http://www.debian.org/Packages/unstable/text/vh.html
|
||||
newsreader, supporting color, MIME [14]http://www.tin.org/
|
||||
|
||||
as well as some that use ncurses for the terminfo support alone:
|
||||
|
||||
@ -402,7 +412,7 @@
|
||||
Who's Who and What's What
|
||||
|
||||
Zeyd Ben-Halim started it from a previous package pcurses, written by
|
||||
Pavel Curtis. Eric S. Raymond continued development. Juergen Pfeifer
|
||||
Pavel Curtis. Eric S. Raymond continued development. Jürgen Pfeifer
|
||||
wrote most of the form and menu libraries. Ongoing work is being done
|
||||
by [17]Thomas Dickey. Thomas Dickey acts as the maintainer for the
|
||||
Free Software Foundation, which holds the copyright on ncurses.
|
||||
@ -442,18 +452,18 @@ References
|
||||
|
||||
1. ftp://ftp.gnu.org/gnu/ncurses/
|
||||
2. ftp://invisible-island.net/ncurses/
|
||||
3. http://invisible-island.net/cdk/
|
||||
4. http://www.vexus.ca/products/CDK/
|
||||
5. http://invisible-island.net/ded/
|
||||
6. http://invisible-island.net/dialog/
|
||||
7. http://lynx.isc.org/release/
|
||||
8. http://www.ibiblio.org/mc/
|
||||
9. http://www.mutt.org/
|
||||
10. http://www.ncftp.com/
|
||||
11. http://www.bostic.com/vi/
|
||||
12. http://dione.ids.pl/~pborys/software/pinfo/
|
||||
13. http://www.tin.org/
|
||||
14. http://www.debian.org/Packages/unstable/text/vh.html
|
||||
3. http://invisible-island.net/xterm/xterm.log.html#xterm_230
|
||||
4. http://invisible-island.net/cdk/
|
||||
5. http://www.vexus.ca/products/CDK/
|
||||
6. http://invisible-island.net/ded/
|
||||
7. http://invisible-island.net/dialog/
|
||||
8. http://lynx.isc.org/release/
|
||||
9. http://www.ibiblio.org/mc/
|
||||
10. http://www.mutt.org/
|
||||
11. http://www.ncftp.com/
|
||||
12. http://www.bostic.com/vi/
|
||||
13. https://alioth.debian.org/projects/pinfo/
|
||||
14. http://www.tin.org/
|
||||
15. http://alioth.debian.org/projects/minicom/
|
||||
16. http://invisible-island.net/vile/
|
||||
17. mailto:dickey@invisible-island.net
|
||||
|
@ -8,26 +8,19 @@ ncurses
|
||||
|
||||
For the import files and directories were pruned by:
|
||||
|
||||
tar -X FREEBSD-Xlist -zxf ncurses-5.6.tar.gz
|
||||
tar -X FREEBSD-Xlist -zxf ncurses-5.7.tar.gz
|
||||
|
||||
check if there are any new bits that we don't want.
|
||||
|
||||
then imported by:
|
||||
The instructions for importing new release and merging to HEAD can be found
|
||||
at FreeBSD wiki:
|
||||
|
||||
cvs import -m 'Import ncurses 5.6-20061217 onto the vendor branch' \
|
||||
src/contrib/ncurses NCURSES v5_6_20061217
|
||||
http://wiki.freebsd.org/SubversionPrimer/VendorImports
|
||||
|
||||
The date in the tag can be obtained from contrib/ncurses/dist.mk.
|
||||
If the version is a snapshot,
|
||||
The version tag can be obtained from contrib/ncurses/dist.mk.
|
||||
|
||||
cvs import -m 'Import ncurses 5.6-20080503 snapshot onto the vendor branch' \
|
||||
src/contrib/ncurses NCURSES v5_6_20080503
|
||||
|
||||
Remove files that are removed in this release in vendor branch (NCURSES)
|
||||
instead of HEAD.
|
||||
|
||||
To make local changes to ncurses, simply patch and commit to the main
|
||||
branch (aka HEAD). Never make local changes on the vendor (NCURSES) branch.
|
||||
To make local changes to ncurses, simply patch and commit to the trunk
|
||||
branch (aka HEAD). Never make local changes on the vendor branch.
|
||||
|
||||
All local changes should be submitted to Thomas Dickey for inclusion in
|
||||
the next vendor release. The author is very willing to help us.
|
||||
@ -39,19 +32,20 @@ ncurses, go to /usr/ports/devel/ncurses and
|
||||
|
||||
Update ncurses_cfg.h and necessary Makefile glues from ${WRKSRC}/build.nowidec.
|
||||
Directory for wide character support is ${WRKSRC}/build.widec
|
||||
You may have to update ncurses-specific glue in termcap.c.
|
||||
You may have to update ncurses-specific glue in termcap.c (check if
|
||||
ncurses/tinfo/read_termcap.c has been changed since last import).
|
||||
|
||||
Current local changes:
|
||||
|
||||
ncurses/tinfo/comp_scan.c
|
||||
rev 1.2: native termcap tweaking
|
||||
r50620: native termcap tweaking (cvs r1.2)
|
||||
|
||||
ncurses/tinfo/lib_termcap.c
|
||||
rev 1.2: native termcap tweaking
|
||||
rev 1.4: remove GCC_UNUSED for rev 1.2
|
||||
r50620: native termcap tweaking (cvs r1.2)
|
||||
r50850: remove GCC_UNUSED for r50620 (cvs r1.4)
|
||||
|
||||
ncurses/tinfo/read_termcap.c
|
||||
This is not used. We have our own src/lib/ncurses/termcap.c
|
||||
|
||||
rafan@FreeBSD.org
|
||||
9-Jan-2007
|
||||
15-Nov-2008
|
||||
|
@ -1,8 +0,0 @@
|
||||
# $FreeBSD$
|
||||
Project: Ncurses (new curses) library
|
||||
ProjectURL: http://www.gnu.org/software/ncurses/
|
||||
Version: 5.6-20080503 snapshot
|
||||
VendorTag: NCURSES
|
||||
VersionTag: v5_6_20080503
|
||||
License: MIT-like
|
||||
Maintainer: rafan
|
@ -1,5 +1,5 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. --
|
||||
-- Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a --
|
||||
-- copy of this software and associated documentation files (the --
|
||||
@ -25,7 +25,7 @@
|
||||
-- sale, use or other dealings in this Software without prior written --
|
||||
-- authorization. --
|
||||
-------------------------------------------------------------------------------
|
||||
-- $Id: INSTALL,v 1.124 2008/03/29 18:07:32 tom Exp $
|
||||
-- $Id: INSTALL,v 1.135 2008/11/02 21:13:51 tom Exp $
|
||||
---------------------------------------------------------------------
|
||||
How to install Ncurses/Terminfo on your system
|
||||
---------------------------------------------------------------------
|
||||
@ -393,6 +393,18 @@ SUMMARY OF CONFIGURE OPTIONS:
|
||||
Compile without scroll-hints code. This option is ignored when
|
||||
hashmap scrolling is configured, which is the default.
|
||||
|
||||
--disable-tic-depends
|
||||
When building shared libraries, normally the tic library is linked to
|
||||
depend upon the ncurses library (and in turn, on the term-library if
|
||||
the --with-termlib option was given). The tic- and term-libraries
|
||||
ABI does not depend on the --enable-widec option. Some packagers have
|
||||
used this to reduce the number of library files which are packaged
|
||||
by using only one copy of those libraries. To make this work properly,
|
||||
the tic library must be built without an explicit dependency on the
|
||||
ncurses (or ncursesw) library. Use this configure option to do that.
|
||||
For example
|
||||
configure --with-ticlib --with-shared --disable-tic-depends
|
||||
|
||||
--disable-tparm-varargs
|
||||
Portable programs should call tparm() using the fixed-length parameter
|
||||
list documented in X/Open. ncurses provides varargs support for this
|
||||
@ -572,6 +584,13 @@ SUMMARY OF CONFIGURE OPTIONS:
|
||||
--enable-warnings
|
||||
Turn on GCC compiler warnings. There should be only a few.
|
||||
|
||||
--enable-weak-symbols
|
||||
If the --with-pthread option is set, check if the compiler supports
|
||||
weak-symbols. If it does, then name the thread-capable library without
|
||||
the "t" (libncurses rather than libncursest), and provide for
|
||||
dynamically loading the pthreads entrypoints at runtime. This allows
|
||||
one to reduce the number of library files for ncurses.
|
||||
|
||||
--enable-wgetch-events
|
||||
Compile with experimental wgetch-events code. See ncurses/README.IZ
|
||||
|
||||
@ -598,6 +617,9 @@ SUMMARY OF CONFIGURE OPTIONS:
|
||||
Normally this is the same as the release version; some ports have
|
||||
special requirements for compatibility.
|
||||
|
||||
This option does not affect linking with libtool, which uses the
|
||||
release major/minor numbers.
|
||||
|
||||
--with-ada-compiler=CMD
|
||||
Specify the Ada95 compiler command (default "gnatmake")
|
||||
|
||||
@ -625,20 +647,32 @@ SUMMARY OF CONFIGURE OPTIONS:
|
||||
to do this if the target compiler has unusual flags which confuse the
|
||||
host compiler.
|
||||
|
||||
You can also set the environment variable $BUILD_CFLAGS rather than
|
||||
use this option.
|
||||
|
||||
--with-build-cppflags=XXX
|
||||
If cross-compiling, specify the host C preprocessor-flags. You might
|
||||
need to do this if the target compiler has unusual flags which confuse
|
||||
the host compiler.
|
||||
|
||||
You can also set the environment variable $BUILD_CPPFLAGS rather than
|
||||
use this option.
|
||||
|
||||
--with-build-ldflags=XXX
|
||||
If cross-compiling, specify the host linker-flags. You might need to
|
||||
do this if the target linker has unusual flags which confuse the host
|
||||
compiler.
|
||||
|
||||
You can also set the environment variable $BUILD_LDFLAGS rather than
|
||||
use this option.
|
||||
|
||||
--with-build-libs=XXX
|
||||
If cross-compiling, the host libraries. You might need to do this if
|
||||
the target environment requires unusual libraries.
|
||||
|
||||
You can also set the environment variable $BUILD_LIBS rather than
|
||||
use this option.
|
||||
|
||||
--with-caps=XXX
|
||||
Specify an alternate terminfo capabilities file, which makes the
|
||||
configure script look for "include/Caps.XXX". A few systems, e.g.,
|
||||
@ -795,6 +829,14 @@ SUMMARY OF CONFIGURE OPTIONS:
|
||||
may be unsigned. Use this option if you need to preserve compatibility
|
||||
with 64-bit executables.
|
||||
|
||||
--with-normal
|
||||
Generate normal (i.e., static) libraries (default).
|
||||
|
||||
Note: on Linux, the configure script will attempt to use the GPM
|
||||
library via the dlsym() function call. Use --without-dlsym to disable
|
||||
this feature, or --without-gpm, depending on whether you wish to use
|
||||
GPM.
|
||||
|
||||
--with-ospeed=TYPE
|
||||
Override type of ospeed variable, which is part of the termcap
|
||||
compatibility interface. In termcap, this is a 'short', which works
|
||||
@ -808,14 +850,6 @@ SUMMARY OF CONFIGURE OPTIONS:
|
||||
those using termcap, do not use the higher speeds. Your application
|
||||
(or system, in general) may or may not.
|
||||
|
||||
--with-normal
|
||||
Generate normal (i.e., static) libraries (default).
|
||||
|
||||
Note: on Linux, the configure script will attempt to use the GPM
|
||||
library via the dlsym() function call. Use --without-dlsym to disable
|
||||
this feature, or --without-gpm, depending on whether you wish to use
|
||||
GPM.
|
||||
|
||||
--with-profile
|
||||
Generate profile-libraries These are named by adding "_p" to the root,
|
||||
e.g., libncurses_p.a
|
||||
@ -898,6 +932,12 @@ SUMMARY OF CONFIGURE OPTIONS:
|
||||
library. As in termlib, there is no ABI difference between the
|
||||
"wide" libticw.so and libtic.so
|
||||
|
||||
NOTE: Overriding the name of the tic library may be useful if you are
|
||||
also using the --with-termlib option to rename libtinfo. If you are
|
||||
not doing that, renaming the tic library can result in conflicting
|
||||
library dependencies for tic and other programs built with the tic
|
||||
library.
|
||||
|
||||
--with-trace
|
||||
Configure the trace() function as part of the all models of the ncurses
|
||||
library. Normally it is part of the debug (libncurses_g) library only.
|
||||
@ -961,6 +1001,94 @@ COMPATIBILITY WITH OLDER VERSIONS OF NCURSES:
|
||||
you may encounter when building a system with different versions of
|
||||
ncurses:
|
||||
|
||||
5.7 (November 2, 2008)
|
||||
Interface changes:
|
||||
|
||||
+ generate linkable stubs for some macros:
|
||||
getattrs
|
||||
|
||||
+ Add new library configuration for tic-library (the non-curses portion
|
||||
of the ncurses library used for the tic program as well as some
|
||||
others such as tack. There is no API change, but makefiles would be
|
||||
changed to use the tic-library built separately.
|
||||
|
||||
tack, distributed separately from ncurses, uses some of the internal
|
||||
_nc_XXX functions, which are declared in the tic.h header file.
|
||||
|
||||
The reason for providing this separate library is that none of the
|
||||
functions in it are suitable for threaded applications.
|
||||
|
||||
+ Add new library configuration (ncursest, ncurseswt) which provides
|
||||
rudimentary support for POSIX threads. This introduces opaque
|
||||
access functions to the WINDOW structure and adds a parameter to
|
||||
several internal functions.
|
||||
|
||||
+ move most internal variables (except tic-library) into data blocks
|
||||
_nc_globals and _nc_prescreen to simplify analysis. Those were
|
||||
globally accessible, but since they were not part of the documented
|
||||
API, there is no ABI change.
|
||||
|
||||
+ changed static tables of strings to be indices into long strings, to
|
||||
improve startup performance. This changes parameter lists for some
|
||||
of the internal functions.
|
||||
|
||||
Added extensions:
|
||||
|
||||
+ add NCURSES_OPAQUE definition in curses.h to control whether internal
|
||||
details of the WINDOW structure are visible to an application. This
|
||||
is always defined when the threaded library is built, and is optional
|
||||
otherwise. New functions for this: is_cleared, is_idcok, is_idlok,
|
||||
is_immedok, is_keypad, is_leaveok, is_nodelay, is_notimeout,
|
||||
is_scrollok, is_syncok, wgetparent and wgetscrreg.
|
||||
|
||||
+ the threaded library (ncursest) also disallows direct updating of
|
||||
global curses-level variables, providing functions (via macros) for
|
||||
obtaining their value. A few of those variables can be modified by
|
||||
the application, using new functions: set_escdelay, set_tabsize
|
||||
|
||||
+ added functions use_window() and use_screen() which wrap a mutex
|
||||
(if threading is configured) around a call to a user-supplied
|
||||
function.
|
||||
|
||||
Added internal functions:
|
||||
_nc_get_alias_table
|
||||
_nc_get_screensize
|
||||
_nc_keyname
|
||||
_nc_screen_of
|
||||
_nc_set_no_padding
|
||||
_nc_tracechar
|
||||
_nc_tracemouse
|
||||
_nc_unctrl
|
||||
_nc_ungetch
|
||||
|
||||
These are used for leak-testing, and are stubs for
|
||||
ABI compatibility when ncurses is not configured for that
|
||||
using the --disable-leaks configure script option:
|
||||
|
||||
_nc_free_and_exit
|
||||
_nc_leaks_tinfo
|
||||
|
||||
Removed internal functions:
|
||||
none
|
||||
|
||||
Modified internal functions:
|
||||
_nc_fifo_dump
|
||||
_nc_find_entry
|
||||
_nc_handle_sigwinch
|
||||
_nc_init_keytry
|
||||
_nc_keypad
|
||||
_nc_locale_breaks_acs
|
||||
_nc_timed_wait
|
||||
_nc_update_screensize
|
||||
|
||||
Use new typedef TRIES to replace "struct tries":
|
||||
|
||||
_nc_add_to_try
|
||||
_nc_expand_try
|
||||
_nc_remove_key
|
||||
_nc_remove_string
|
||||
_nc_trace_tries
|
||||
|
||||
5.6 (December 17, 2006)
|
||||
Interface changes:
|
||||
|
||||
|
@ -349,8 +349,10 @@
|
||||
./doc/html/man/curs_instr.3x.html
|
||||
./doc/html/man/curs_inwstr.3x.html
|
||||
./doc/html/man/curs_kernel.3x.html
|
||||
./doc/html/man/curs_legacy.3x.html
|
||||
./doc/html/man/curs_mouse.3x.html
|
||||
./doc/html/man/curs_move.3x.html
|
||||
./doc/html/man/curs_opaque.3x.html
|
||||
./doc/html/man/curs_outopts.3x.html
|
||||
./doc/html/man/curs_overlay.3x.html
|
||||
./doc/html/man/curs_pad.3x.html
|
||||
@ -364,6 +366,7 @@
|
||||
./doc/html/man/curs_termattrs.3x.html
|
||||
./doc/html/man/curs_termcap.3x.html
|
||||
./doc/html/man/curs_terminfo.3x.html
|
||||
./doc/html/man/curs_threads.3x.html
|
||||
./doc/html/man/curs_touch.3x.html
|
||||
./doc/html/man/curs_trace.3x.html
|
||||
./doc/html/man/curs_util.3x.html
|
||||
@ -555,6 +558,7 @@
|
||||
./man/curs_inwstr.3x
|
||||
./man/curs_kernel.3x
|
||||
./man/curs_legacy.3x
|
||||
./man/curs_memleaks.3x
|
||||
./man/curs_mouse.3x
|
||||
./man/curs_move.3x
|
||||
./man/curs_opaque.3x
|
||||
@ -700,6 +704,7 @@
|
||||
./misc/ncurses-config.in
|
||||
./misc/ncurses.def
|
||||
./misc/ncurses.ref
|
||||
./misc/ncurses.supp
|
||||
./misc/panel.def
|
||||
./misc/panel.ref
|
||||
./misc/run_tic.in
|
||||
|
@ -25,7 +25,7 @@
|
||||
-- sale, use or other dealings in this Software without prior written --
|
||||
-- authorization. --
|
||||
-------------------------------------------------------------------------------
|
||||
-- $Id: NEWS,v 1.1233 2008/05/03 23:14:39 tom Exp $
|
||||
-- $Id: NEWS,v 1.1320 2008/11/02 00:56:22 tom Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This is a log of changes that ncurses has gone through since Zeyd started
|
||||
@ -45,6 +45,238 @@ See the AUTHORS file for the corresponding full names.
|
||||
Changes through 1.9.9e did not credit all contributions;
|
||||
it is not possible to add this information.
|
||||
|
||||
20081102 5.7 release for upload to ftp.gnu.org
|
||||
|
||||
20081025
|
||||
+ add a manpage to discuss memory leaks.
|
||||
+ add support for shared libraries for QNX (other than libtool, which
|
||||
does not work well on that platform).
|
||||
+ build-fix for QNX C++ binding.
|
||||
|
||||
20081018
|
||||
+ build-fixes for OS/2 EMX.
|
||||
+ modify form library to accept control characters such as newline
|
||||
in set_field_buffer(), which is compatible with Solaris (report by
|
||||
Nit Khair).
|
||||
+ modify configure script to assume --without-hashed-db when
|
||||
--disable-database is used.
|
||||
+ add "-e" option in ncurses/Makefile.in when generating source-files
|
||||
to force earlier exit if the build environment fails unexpectedly
|
||||
(prompted by patch by Adrian Bunk).
|
||||
+ change configure script to use CF_UTF8_LIB, improved variant of
|
||||
CF_LIBUTF8.
|
||||
|
||||
20081012
|
||||
+ add teraterm4.59 terminfo entry, use that as primary teraterm entry, rename
|
||||
original to teraterm2.3 -TD
|
||||
+ update "gnome" terminfo to 2.22.3 -TD
|
||||
+ update "konsole" terminfo to 1.6.6, needs today's fix for tic -TD
|
||||
+ add "aterm" terminfo -TD
|
||||
+ add "linux2.6.26" terminfo -TD
|
||||
+ add logic to tic for cancelling strings in user-defined capabilities,
|
||||
overlooked til now.
|
||||
|
||||
20081011
|
||||
+ update html documentation.
|
||||
+ add -m and -s options to test/keynames.c and test/key_names.c to test
|
||||
the meta() function with keyname() or key_name(), respectively.
|
||||
+ correct return value of key_name() on error; it is null.
|
||||
+ document some unresolved issues for rpath and pthreads in TO-DO.
|
||||
+ fix a missing prototype for ioctl() on OpenBSD in tset.c
|
||||
+ add configure option --disable-tic-depends to make explicit whether
|
||||
tic library depends on ncurses/ncursesw library, amends change from
|
||||
20080823 (prompted by Debian #501421).
|
||||
|
||||
20081004
|
||||
+ some build-fixes for configure --disable-ext-funcs (incomplete, but
|
||||
works for C/C++ parts).
|
||||
+ improve configure-check for awks unable to handle large strings, e.g.
|
||||
AIX 5.1 whose awk silently gives up on large printf's.
|
||||
|
||||
20080927
|
||||
+ fix build for --with-dmalloc by workaround for redefinition of
|
||||
strndup between string.h and dmalloc.h
|
||||
+ fix build for --disable-sigwinch
|
||||
+ add environment variable NCURSES_GPM_TERMS to allow override to use
|
||||
GPM on terminals other than "linux", etc.
|
||||
+ disable GPM mouse support when $TERM does not happen to contain
|
||||
"linux", since Gpm_Open() no longer limits its assertion to terminals
|
||||
that it might handle, e.g., within "screen" in xterm.
|
||||
+ reset mouse file-descriptor when unloading GPM library (report by
|
||||
Miroslav Lichvar).
|
||||
+ fix build for --disable-leaks --enable-widec --with-termlib
|
||||
> patch by Juergen Pfeifer:
|
||||
+ use improved initialization for soft-label keys in Ada95 sample code.
|
||||
+ discard internal symbol _nc_slk_format (unused since 20080112).
|
||||
+ move call of slk_paint_info() from _nc_slk_initialize() to
|
||||
slk_intern_refresh(), improving initialization.
|
||||
|
||||
20080925
|
||||
+ fix bug in mouse code for GPM from 20080920 changes (reported in
|
||||
Debian #500103, also Miroslav Lichvar).
|
||||
|
||||
20080920
|
||||
+ fix shared-library rules for cygwin with tic- and tinfo-libraries.
|
||||
+ fix a memory leak when failure to connect to GPM.
|
||||
+ correct check for notimeout() in wgetch() (report on linux.redhat
|
||||
newsgroup by FurtiveBertie).
|
||||
+ add an example warning-suppression file for valgrind,
|
||||
misc/ncurses.supp (based on example from Reuben Thomas)
|
||||
|
||||
20080913
|
||||
+ change shared-library configuration for OpenBSD, make rpath work.
|
||||
+ build-fixes for using libutf8, e.g., on OpenBSD 3.7
|
||||
|
||||
20080907
|
||||
+ corrected fix for --enable-weak-symbols (report by Frederic L W
|
||||
Meunier).
|
||||
|
||||
20080906
|
||||
+ corrected gcc options for building shared libraries on IRIX64.
|
||||
+ add configure check for awk programs unable to handle big-strings,
|
||||
use that to improve the default for --enable-big-strings option.
|
||||
+ makefile-fixes for --enable-weak-symbols (report by Frederic L W
|
||||
Meunier).
|
||||
+ update test/configure script.
|
||||
+ adapt ifdef's from library to make test/view.c build when mbrtowc()
|
||||
is unavailable, e.g., with HPUX 10.20.
|
||||
+ add configure check for wcsrtombs, mbsrtowcs, which are used in
|
||||
test/ncurses.c, and use wcstombs, mbstowcs instead if available,
|
||||
fixing build of ncursew for HPUX 11.00
|
||||
|
||||
20080830
|
||||
+ fixes to make Ada95 demo_panels() example work.
|
||||
+ modify Ada95 'rain' test program to accept keyboard commands like the
|
||||
C-version.
|
||||
+ modify BeOS-specific ifdef's to build on Haiku (patch by Scott
|
||||
Mccreary).
|
||||
+ add configure-check to see if the std namespace is legal for cerr
|
||||
and endl, to fix a build issue with Tru64.
|
||||
+ consistently use NCURSES_BOOL in lib_gen.c
|
||||
+ filter #line's from lib_gen.c
|
||||
+ change delimiter in MKlib_gen.sh from '%' to '@', to avoid
|
||||
substitution by IBM xlc to '#' as part of its extensions to digraphs.
|
||||
+ update config.guess, config.sub from
|
||||
http://savannah.gnu.org/projects/config
|
||||
(caveat - its maintainer removed support for older Linux systems).
|
||||
|
||||
20080823
|
||||
+ modify configure check for pthread library to work with OSF/1 5.1,
|
||||
which uses #define's to associate its header and library.
|
||||
+ use pthread_mutexattr_init() for initializing pthread_mutexattr_t,
|
||||
makes threaded code work on HPUX 11.23
|
||||
+ fix a bug in demo_menus in freeing menus (cf: 20080804).
|
||||
+ modify configure script for the case where tic library is used (and
|
||||
possibly renamed) to remove its dependency upon ncurses/ncursew
|
||||
library (patch by Dr Werner Fink).
|
||||
+ correct manpage for menu_fore() which gave wrong default for
|
||||
the attribute used to display a selected entry (report by Mike Gran).
|
||||
+ add Eterm-256color, Eterm-88color and rxvt-88color (prompted by
|
||||
Debian #495815) -TD
|
||||
|
||||
20080816
|
||||
+ add configure option --enable-weak-symbols to turn on new feature.
|
||||
+ add configure-check for availability of weak symbols.
|
||||
+ modify linkage with pthread library to use weak symbols so that
|
||||
applications not linked to that library will not use the mutexes,
|
||||
etc. This relies on gcc, and may be platform-specific (patch by Dr
|
||||
Werner Fink).
|
||||
+ add note to INSTALL to document limitation of renaming of tic library
|
||||
using the --with-ticlib configure option (report by Dr Werner Fink).
|
||||
+ document (in manpage) why tputs does not detect I/O errors (prompted
|
||||
by comments by Samuel Thibault).
|
||||
+ fix remaining warnings from Klocwork report.
|
||||
|
||||
20080804
|
||||
+ modify _nc_panelhook() data to account for a permanent memory leak.
|
||||
+ fix memory leaks in test/demo_menus
|
||||
+ fix most warnings from Klocwork tool (report by Larry Zhou).
|
||||
+ modify configure script CF_XOPEN_SOURCE macro to add case for
|
||||
"dragonfly" from xterm #236 changes.
|
||||
+ modify configure script --with-hashed-db to let $LIBS override the
|
||||
search for the db library (prompted by report by Samson Pierre).
|
||||
|
||||
20080726
|
||||
+ build-fixes for gcc 4.3.1 (changes to gnat "warnings", and C inlining
|
||||
thresholds).
|
||||
|
||||
20080713
|
||||
+ build-fix (reports by Christian Ebert, Funda Wang).
|
||||
|
||||
20080712
|
||||
+ compiler-warning fixes for Solaris.
|
||||
|
||||
20080705
|
||||
+ use NCURSES_MOUSE_MASK() in definition of BUTTON_RELEASE(), etc., to
|
||||
make those work properly with the "--enable-ext-mouse" configuration
|
||||
(cf: 20050205).
|
||||
+ improve documentation of build-cc options in INSTALL.
|
||||
+ work-around a bug in gcc 4.2.4 on AIX, which does not pass the
|
||||
-static/-dynamic flags properly to linker, causing test/bs to
|
||||
not link.
|
||||
|
||||
20080628
|
||||
+ correct some ifdef's needed for the broken-linker configuration.
|
||||
+ make debugging library's $BAUDRATE feature work for termcap
|
||||
interface.
|
||||
+ make $NCURSES_NO_PADDING feature work for termcap interface (prompted
|
||||
by comment on FreeBSD mailing list).
|
||||
+ add screen.mlterm terminfo entry -TD
|
||||
+ improve mlterm and mlterm+pcfkeys terminfo entries -TD
|
||||
|
||||
20080621
|
||||
+ regenerated html documentation.
|
||||
+ expand manpage description of parameters for form_driver() and
|
||||
menu_driver() (prompted by discussion with Adam Spragg).
|
||||
+ add null-pointer checks for cur_term in baudrate() and
|
||||
def_shell_mode(), def_prog_mode()
|
||||
+ fix some memory leaks in delscreen() and wide acs.
|
||||
|
||||
20080614
|
||||
+ modify test/ditto.c to illustrate multi-threaded use_screen().
|
||||
+ change CC_SHARED_OPTS from -KPIC to -xcode=pic32 for Solaris.
|
||||
+ add "-shared" option to MK_SHARED_LIB for gcc on Solaris (report
|
||||
by Poor Yorick).
|
||||
|
||||
20080607
|
||||
+ finish changes to wgetch(), making it switch as needed to the
|
||||
window's actual screen when calling wrefresh() and wgetnstr(). That
|
||||
allows wgetch() to get used concurrently in different threads with
|
||||
some minor restrictions, e.g., the application should not delete a
|
||||
window which is being used in a wgetch().
|
||||
+ simplify mutex's, combining the window- and screen-mutex's.
|
||||
|
||||
20080531
|
||||
+ modify wgetch() to use the screen which corresponds to its window
|
||||
parameter rather than relying on SP; some dependent functions still
|
||||
use SP internally.
|
||||
+ factor out most use of SP in lib_mouse.c, using parameter.
|
||||
+ add internal _nc_keyname(), replacing keyname() to associate with a
|
||||
particular SCREEN rather than the global SP.
|
||||
+ add internal _nc_unctrl(), replacing unctrl() to associate with a
|
||||
particular SCREEN rather than the global SP.
|
||||
+ add internal _nc_tracemouse(), replacing _tracemouse() to eliminate
|
||||
its associated global buffer _nc_globals.tracemse_buf now in SCREEN.
|
||||
+ add internal _nc_tracechar(), replacing _tracechar() to use SCREEN in
|
||||
preference to the global _nc_globals.tracechr_buf buffer.
|
||||
|
||||
20080524
|
||||
+ modify _nc_keypad() to make it switch temporarily as needed to the
|
||||
screen which must be updated.
|
||||
+ wrap cur_term variable to help make _nc_keymap() thread-safe, and
|
||||
always set the screen's copy of this variable in set_curterm().
|
||||
+ restore curs_set() state after endwin()/refresh() (report/patch
|
||||
Miroslav Lichvar)
|
||||
|
||||
20080517
|
||||
+ modify configure script to note that --enable-ext-colors and
|
||||
--enable-ext-mouse are not experimental, but extensions from
|
||||
the ncurses ABI 5.
|
||||
+ corrected manpage description of setcchar() (discussion with
|
||||
Emanuele Giaquinta).
|
||||
+ fix for adding a non-spacing character at the beginning of a line
|
||||
(report/patch by Miroslav Lichvar).
|
||||
|
||||
20080503
|
||||
+ modify screen.* terminfo entries using new screen+fkeys to fix
|
||||
overridden keys in screen.rxvt (Debian #478094) -TD
|
||||
@ -375,7 +607,7 @@ it is not possible to add this information.
|
||||
|
||||
20070609
|
||||
+ add test/key_name.c
|
||||
+ add stdscr cases to test/inchs.c and test_inch_wide.c
|
||||
+ add stdscr cases to test/inchs.c and test/inch_wide.c
|
||||
+ update test/configure
|
||||
+ correct formatting of DEL (0x7f) in _nc_vischar().
|
||||
+ null-terminate result of wunctrl().
|
||||
@ -596,7 +828,7 @@ it is not possible to add this information.
|
||||
shared libraries on Darwin (report by Michail Vidiassov).
|
||||
|
||||
20070210
|
||||
+ add test/inchs.c, test_inch_wide.c, to test win_wchnstr().
|
||||
+ add test/inchs.c, test/inch_wide.c, to test win_wchnstr().
|
||||
+ remove libdl from library list for termlib (report by Miroslav
|
||||
Lichvar).
|
||||
+ fix configure.in to allow --without-progs --with-termlib (patch by
|
||||
|
@ -1,5 +1,5 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. --
|
||||
-- Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a --
|
||||
-- copy of this software and associated documentation files (the --
|
||||
@ -25,7 +25,7 @@
|
||||
-- sale, use or other dealings in this Software without prior written --
|
||||
-- authorization. --
|
||||
-------------------------------------------------------------------------------
|
||||
-- $Id: TO-DO,v 1.49 2007/02/03 16:29:17 tom Exp $
|
||||
-- $Id: TO-DO,v 1.51 2008/10/11 19:22:27 tom Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
SHORT-TERM TO-DO ITEMS:
|
||||
@ -61,6 +61,17 @@ Known Problems:
|
||||
+ vid_attr() should support the set_a_attributes (sgr1) string, but does not.
|
||||
There appear to be no terminals that require that functionality.
|
||||
|
||||
+ the configure --disable-ext-funcs option does not work for Ada95 tree.
|
||||
|
||||
+ the --with-pthread configuration builds for Cygwin, but does not work
|
||||
properly (test/worm.c shows all of the worms in the same location).
|
||||
|
||||
+ the --enable-rpath configure option builds for the corresponding platforms;
|
||||
however combining it with --with-ticlib and --with-termlib does not always
|
||||
produce libraries that can be run without setting environment variables.
|
||||
Building those with libtool does not work either. (This is a problem with
|
||||
the BSD platforms).
|
||||
|
||||
Portability (or lack thereof):
|
||||
|
||||
+ Users of older System V UNIXes (but not Solaris, and probably not SVr4) may
|
||||
|
546
contrib/ncurses/aclocal.m4
vendored
546
contrib/ncurses/aclocal.m4
vendored
@ -28,7 +28,7 @@ dnl***************************************************************************
|
||||
dnl
|
||||
dnl Author: Thomas E. Dickey 1995-on
|
||||
dnl
|
||||
dnl $Id: aclocal.m4,v 1.447 2008/04/12 23:49:55 tom Exp $
|
||||
dnl $Id: aclocal.m4,v 1.470 2008/10/25 22:15:32 tom Exp $
|
||||
dnl Macros used in NCURSES auto-configuration script.
|
||||
dnl
|
||||
dnl These macros are maintained separately from NCURSES. The copyright on
|
||||
@ -261,6 +261,28 @@ if test -n "$1" ; then
|
||||
fi
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_ADD_SUBDIR_PATH version: 2 updated: 2007/07/29 10:12:59
|
||||
dnl ------------------
|
||||
dnl Append to a search-list for a nonstandard header/lib-file
|
||||
dnl $1 = the variable to return as result
|
||||
dnl $2 = the package name
|
||||
dnl $3 = the subdirectory, e.g., bin, include or lib
|
||||
dnl $4 = the directory under which we will test for subdirectories
|
||||
dnl $5 = a directory that we do not want $4 to match
|
||||
AC_DEFUN([CF_ADD_SUBDIR_PATH],
|
||||
[
|
||||
test "$4" != "$5" && \
|
||||
test -d "$4" && \
|
||||
ifelse([$5],NONE,,[(test $5 = NONE || test -d $5) &&]) {
|
||||
test -n "$verbose" && echo " ... testing for $3-directories under $4"
|
||||
test -d $4/$3 && $1="[$]$1 $4/$3"
|
||||
test -d $4/$3/$2 && $1="[$]$1 $4/$3/$2"
|
||||
test -d $4/$3/$2/$3 && $1="[$]$1 $4/$3/$2/$3"
|
||||
test -d $4/$2/$3 && $1="[$]$1 $4/$2/$3"
|
||||
test -d $4/$2/$3/$2 && $1="[$]$1 $4/$2/$3/$2"
|
||||
}
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_ANSI_CC_CHECK version: 9 updated: 2001/12/30 17:53:34
|
||||
dnl ----------------
|
||||
dnl This is adapted from the macros 'fp_PROG_CC_STDC' and 'fp_C_PROTOTYPES'
|
||||
@ -331,6 +353,30 @@ You have the following choices:
|
||||
fi
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_AWK_BIG_PRINTF version: 2 updated: 2008/10/04 17:16:18
|
||||
dnl -----------------
|
||||
dnl Check if awk can handle big strings using printf. Some older versions of
|
||||
dnl awk choke on large strings passed via "%s".
|
||||
dnl
|
||||
dnl $1 = desired string size
|
||||
dnl $2 = variable to set with result
|
||||
AC_DEFUN([CF_AWK_BIG_PRINTF],
|
||||
[
|
||||
case x$AWK in #(vi
|
||||
x)
|
||||
eval $2=no
|
||||
;;
|
||||
*) #(vi
|
||||
if ( ${AWK} 'BEGIN { xx = "x"; while (length(xx) < $1) { xx = xx "x"; }; printf("%s\n", xx); }' \
|
||||
| $AWK '{ printf "%d\n", length([$]0); }' | $AWK 'BEGIN { eqls=0; recs=0; } { recs++; if ([$]0 == 12000) eqls++; } END { if (recs != 1 || eqls != 1) exit 1; }' 2>/dev/null >/dev/null ) ; then
|
||||
eval $2=yes
|
||||
else
|
||||
eval $2=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_BOOL_DECL version: 8 updated: 2004/01/30 15:51:18
|
||||
dnl ------------
|
||||
dnl Test if 'bool' is a builtin type in the configured C++ compiler. Some
|
||||
@ -649,13 +695,14 @@ if test ".$system_name" != ".$cf_cv_system_name" ; then
|
||||
fi
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_CHECK_ERRNO version: 9 updated: 2001/12/30 18:03:23
|
||||
dnl CF_CHECK_ERRNO version: 10 updated: 2008/08/22 16:33:22
|
||||
dnl --------------
|
||||
dnl Check for data that is usually declared in <stdio.h> or <errno.h>, e.g.,
|
||||
dnl the 'errno' variable. Define a DECL_xxx symbol if we must declare it
|
||||
dnl ourselves.
|
||||
dnl
|
||||
dnl $1 = the name to check
|
||||
dnl $2 = the assumed type
|
||||
AC_DEFUN([CF_CHECK_ERRNO],
|
||||
[
|
||||
AC_CACHE_CHECK(if external $1 is declared, cf_cv_dcl_$1,[
|
||||
@ -666,7 +713,7 @@ AC_CACHE_CHECK(if external $1 is declared, cf_cv_dcl_$1,[
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h> ],
|
||||
[long x = (long) $1],
|
||||
ifelse($2,,int,$2) x = (ifelse($2,,int,$2)) $1,
|
||||
[cf_cv_dcl_$1=yes],
|
||||
[cf_cv_dcl_$1=no])
|
||||
])
|
||||
@ -677,7 +724,7 @@ if test "$cf_cv_dcl_$1" = no ; then
|
||||
fi
|
||||
|
||||
# It's possible (for near-UNIX clones) that the data doesn't exist
|
||||
CF_CHECK_EXTERN_DATA($1,int)
|
||||
CF_CHECK_EXTERN_DATA($1,ifelse($2,,int,$2))
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_CHECK_EXTERN_DATA version: 3 updated: 2001/12/30 18:03:23
|
||||
@ -920,6 +967,20 @@ if test "$with_no_leaks" = yes ; then
|
||||
fi
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_ENABLE_RPATH version: 1 updated: 2008/09/13 10:22:30
|
||||
dnl ---------------
|
||||
dnl Check if the rpath option should be used, setting cache variable
|
||||
dnl cf_cv_ld_rpath if so.
|
||||
AC_DEFUN([CF_ENABLE_RPATH],
|
||||
[
|
||||
AC_MSG_CHECKING(if rpath option should be used)
|
||||
AC_ARG_ENABLE(rpath,
|
||||
[ --enable-rpath use rpath option when generating shared libraries],
|
||||
[cf_cv_ld_rpath=$enableval],
|
||||
[cf_cv_ld_rpath=no])
|
||||
AC_MSG_RESULT($cf_cv_ld_rpath)
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_ERRNO version: 5 updated: 1997/11/30 12:44:39
|
||||
dnl --------
|
||||
dnl Check if 'errno' is declared in <errno.h>
|
||||
@ -958,6 +1019,118 @@ AC_MSG_RESULT($cf_result)
|
||||
CXXFLAGS="$cf_save_CXXFLAGS"
|
||||
])
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_FIND_LINKAGE version: 12 updated: 2007/07/29 20:13:53
|
||||
dnl ---------------
|
||||
dnl Find a library (specifically the linkage used in the code fragment),
|
||||
dnl searching for it if it is not already in the library path.
|
||||
dnl See also CF_ADD_SEARCHPATH.
|
||||
dnl
|
||||
dnl Parameters (4-on are optional):
|
||||
dnl $1 = headers for library entrypoint
|
||||
dnl $2 = code fragment for library entrypoint
|
||||
dnl $3 = the library name without the "-l" option or ".so" suffix.
|
||||
dnl $4 = action to perform if successful (default: update CPPFLAGS, etc)
|
||||
dnl $5 = action to perform if not successful
|
||||
dnl $6 = module name, if not the same as the library name
|
||||
dnl $7 = extra libraries
|
||||
dnl
|
||||
dnl Sets these variables:
|
||||
dnl $cf_cv_find_linkage_$3 - yes/no according to whether linkage is found
|
||||
dnl $cf_cv_header_path_$3 - include-directory if needed
|
||||
dnl $cf_cv_library_path_$3 - library-directory if needed
|
||||
dnl $cf_cv_library_file_$3 - library-file if needed, e.g., -l$3
|
||||
AC_DEFUN([CF_FIND_LINKAGE],[
|
||||
|
||||
# If the linkage is not already in the $CPPFLAGS/$LDFLAGS configuration, these
|
||||
# will be set on completion of the AC_TRY_LINK below.
|
||||
cf_cv_header_path_$3=
|
||||
cf_cv_library_path_$3=
|
||||
|
||||
CF_MSG_LOG([Starting [FIND_LINKAGE]($3,$6)])
|
||||
|
||||
AC_TRY_LINK([$1],[$2],
|
||||
cf_cv_find_linkage_$3=yes,[
|
||||
cf_cv_find_linkage_$3=no
|
||||
|
||||
CF_MSG_LOG([Searching for headers in [FIND_LINKAGE]($3,$6)])
|
||||
|
||||
cf_save_CPPFLAGS="$CPPFLAGS"
|
||||
cf_test_CPPFLAGS="$CPPFLAGS"
|
||||
|
||||
CF_HEADER_PATH(cf_search,ifelse([$6],,[$3],[$6]))
|
||||
for cf_cv_header_path_$3 in $cf_search
|
||||
do
|
||||
if test -d $cf_cv_header_path_$3 ; then
|
||||
CF_VERBOSE(... testing $cf_cv_header_path_$3)
|
||||
CPPFLAGS="$cf_save_CPPFLAGS -I$cf_cv_header_path_$3"
|
||||
AC_TRY_COMPILE([$1],[$2],[
|
||||
CF_VERBOSE(... found $3 headers in $cf_cv_header_path_$3)
|
||||
cf_cv_find_linkage_$3=maybe
|
||||
cf_test_CPPFLAGS="$CPPFLAGS"
|
||||
break],[
|
||||
CPPFLAGS="$cf_save_CPPFLAGS"
|
||||
])
|
||||
fi
|
||||
done
|
||||
|
||||
if test "$cf_cv_find_linkage_$3" = maybe ; then
|
||||
|
||||
CF_MSG_LOG([Searching for $3 library in [FIND_LINKAGE]($3,$6)])
|
||||
|
||||
cf_save_LIBS="$LIBS"
|
||||
cf_save_LDFLAGS="$LDFLAGS"
|
||||
|
||||
ifelse([$6],,,[
|
||||
CPPFLAGS="$cf_test_CPPFLAGS"
|
||||
LIBS="-l$3 $7 $cf_save_LIBS"
|
||||
AC_TRY_LINK([$1],[$2],[
|
||||
CF_VERBOSE(... found $3 library in system)
|
||||
cf_cv_find_linkage_$3=yes])
|
||||
CPPFLAGS="$cf_save_CPPFLAGS"
|
||||
LIBS="$cf_save_LIBS"
|
||||
])
|
||||
|
||||
if test "$cf_cv_find_linkage_$3" != yes ; then
|
||||
CF_LIBRARY_PATH(cf_search,$3)
|
||||
for cf_cv_library_path_$3 in $cf_search
|
||||
do
|
||||
if test -d $cf_cv_library_path_$3 ; then
|
||||
CF_VERBOSE(... testing $cf_cv_library_path_$3)
|
||||
CPPFLAGS="$cf_test_CPPFLAGS"
|
||||
LIBS="-l$3 $7 $cf_save_LIBS"
|
||||
LDFLAGS="$cf_save_LDFLAGS -L$cf_cv_library_path_$3"
|
||||
AC_TRY_LINK([$1],[$2],[
|
||||
CF_VERBOSE(... found $3 library in $cf_cv_library_path_$3)
|
||||
cf_cv_find_linkage_$3=yes
|
||||
cf_cv_library_file_$3="-l$3"
|
||||
break],[
|
||||
CPPFLAGS="$cf_save_CPPFLAGS"
|
||||
LIBS="$cf_save_LIBS"
|
||||
LDFLAGS="$cf_save_LDFLAGS"
|
||||
])
|
||||
fi
|
||||
done
|
||||
LIBS="$cf_save_LIBS"
|
||||
CPPFLAGS="$cf_save_CPPFLAGS"
|
||||
LDFLAGS="$cf_save_LDFLAGS"
|
||||
fi
|
||||
|
||||
else
|
||||
cf_cv_find_linkage_$3=no
|
||||
fi
|
||||
],$7)
|
||||
|
||||
if test "$cf_cv_find_linkage_$3" = yes ; then
|
||||
ifelse([$4],,[
|
||||
CF_ADD_INCDIR($cf_cv_header_path_$3)
|
||||
CF_ADD_LIBDIR($cf_cv_library_path_$3)
|
||||
LIBS="-l$3 $LIBS"
|
||||
],[$4])
|
||||
else
|
||||
ifelse([$5],,AC_MSG_WARN(Cannot find $3 library),[$5])
|
||||
fi
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_FUNC_DLSYM version: 1 updated: 2004/06/16 20:52:45
|
||||
dnl -------------
|
||||
dnl Test for dlsym() and related functions, as well as libdl.
|
||||
@ -1278,7 +1451,7 @@ if test "$GCC" = yes ; then
|
||||
fi
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_GCC_WARNINGS version: 22 updated: 2007/07/29 09:55:12
|
||||
dnl CF_GCC_WARNINGS version: 23 updated: 2008/07/26 17:54:02
|
||||
dnl ---------------
|
||||
dnl Check if the compiler supports useful warning options. There's a few that
|
||||
dnl we don't use, simply because they're too noisy:
|
||||
@ -1373,7 +1546,7 @@ then
|
||||
;;
|
||||
Winline) #(vi
|
||||
case $GCC_VERSION in
|
||||
3.3*)
|
||||
[[34]].*)
|
||||
CF_VERBOSE(feature is broken in gcc $GCC_VERSION)
|
||||
continue;;
|
||||
esac
|
||||
@ -1715,7 +1888,7 @@ fi
|
||||
])
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_HASHED_DB_LIBS version: 7 updated: 2007/12/01 15:01:37
|
||||
dnl CF_HASHED_DB_LIBS version: 8 updated: 2008/08/04 06:18:06
|
||||
dnl -----------------
|
||||
dnl Given that we have the header and version for hashed database, find the
|
||||
dnl library information.
|
||||
@ -1723,7 +1896,7 @@ AC_DEFUN([CF_HASHED_DB_LIBS],
|
||||
[
|
||||
AC_CACHE_CHECK(for db libraries, cf_cv_hashed_db_libs,[
|
||||
cf_cv_hashed_db_libs=unknown
|
||||
for cf_db_libs in db$cf_cv_hashed_db_version db-$cf_cv_hashed_db_version db ''
|
||||
for cf_db_libs in "" db$cf_cv_hashed_db_version db-$cf_cv_hashed_db_version db ''
|
||||
do
|
||||
cf_save_libs="$LIBS"
|
||||
if test -n "$cf_db_libs"; then
|
||||
@ -1823,6 +1996,27 @@ $ac_includes_default
|
||||
])
|
||||
done
|
||||
])
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_HEADER_PATH version: 8 updated: 2002/11/10 14:46:59
|
||||
dnl --------------
|
||||
dnl Construct a search-list for a nonstandard header-file
|
||||
AC_DEFUN([CF_HEADER_PATH],
|
||||
[CF_SUBDIR_PATH($1,$2,include)
|
||||
test "$includedir" != NONE && \
|
||||
test "$includedir" != "/usr/include" && \
|
||||
test -d "$includedir" && {
|
||||
test -d $includedir && $1="[$]$1 $includedir"
|
||||
test -d $includedir/$2 && $1="[$]$1 $includedir/$2"
|
||||
}
|
||||
|
||||
test "$oldincludedir" != NONE && \
|
||||
test "$oldincludedir" != "/usr/include" && \
|
||||
test -d "$oldincludedir" && {
|
||||
test -d $oldincludedir && $1="[$]$1 $oldincludedir"
|
||||
test -d $oldincludedir/$2 && $1="[$]$1 $oldincludedir/$2"
|
||||
}
|
||||
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_HELP_MESSAGE version: 3 updated: 1998/01/14 10:56:23
|
||||
@ -1949,7 +2143,7 @@ ifdef([AC_FUNC_FSEEKO],[
|
||||
])
|
||||
])
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_LDFLAGS_STATIC version: 2 updated: 2007/04/28 15:25:27
|
||||
dnl CF_LDFLAGS_STATIC version: 4 updated: 2008/10/18 17:58:20
|
||||
dnl -----------------
|
||||
dnl Check for compiler/linker flags used to temporarily force usage of static
|
||||
dnl libraries. This depends on the compiler and platform. Use this to help
|
||||
@ -1958,8 +2152,16 @@ dnl the list of linker options and libraries.
|
||||
AC_DEFUN([CF_LDFLAGS_STATIC],[
|
||||
|
||||
if test "$GCC" = yes ; then
|
||||
LDFLAGS_STATIC=-static
|
||||
LDFLAGS_SHARED=-dynamic
|
||||
case $cf_cv_system_name in #(
|
||||
OS/2*|os2*|aix[[45]]*) #( vi
|
||||
LDFLAGS_STATIC=
|
||||
LDFLAGS_SHARED=
|
||||
;;
|
||||
*) #( normally, except when broken
|
||||
LDFLAGS_STATIC=-static
|
||||
LDFLAGS_SHARED=-dynamic
|
||||
;;
|
||||
esac
|
||||
else
|
||||
case $cf_cv_system_name in #(
|
||||
aix[[45]]*) #( from ld manpage
|
||||
@ -1991,43 +2193,30 @@ AC_SUBST(LDFLAGS_STATIC)
|
||||
AC_SUBST(LDFLAGS_SHARED)
|
||||
])
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_LIBUTF8 version: 2 updated: 2002/01/19 22:51:32
|
||||
dnl ----------
|
||||
dnl Check for libutf8
|
||||
AC_DEFUN([CF_LIBUTF8],
|
||||
[
|
||||
AC_CACHE_CHECK(for putwc in libutf8,cf_cv_libutf8,[
|
||||
cf_save_LIBS="$LIBS"
|
||||
LIBS="-lutf8 $LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <libutf8.h>],[putwc(0,0);],
|
||||
[cf_cv_libutf8=yes],
|
||||
[cf_cv_libutf8=no])
|
||||
LIBS="$cf_save_LIBS"
|
||||
])
|
||||
|
||||
if test "$cf_cv_libutf8" = yes ; then
|
||||
AC_DEFINE(HAVE_LIBUTF8_H)
|
||||
LIBS="-lutf8 $LIBS"
|
||||
fi
|
||||
])dnl
|
||||
dnl CF_LIBRARY_PATH version: 7 updated: 2002/11/10 14:46:59
|
||||
dnl ---------------
|
||||
dnl Construct a search-list for a nonstandard library-file
|
||||
AC_DEFUN([CF_LIBRARY_PATH],
|
||||
[CF_SUBDIR_PATH($1,$2,lib)])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_LIB_PREFIX version: 7 updated: 2001/01/12 01:23:48
|
||||
dnl CF_LIB_PREFIX version: 8 updated: 2008/09/13 11:34:16
|
||||
dnl -------------
|
||||
dnl Compute the library-prefix for the given host system
|
||||
dnl $1 = variable to set
|
||||
AC_DEFUN([CF_LIB_PREFIX],
|
||||
[
|
||||
case $cf_cv_system_name in
|
||||
OS/2*) LIB_PREFIX='' ;;
|
||||
os2*) LIB_PREFIX='' ;;
|
||||
*) LIB_PREFIX='lib' ;;
|
||||
case $cf_cv_system_name in #(vi
|
||||
OS/2*|os2*) #(vi
|
||||
LIB_PREFIX=''
|
||||
;;
|
||||
*) LIB_PREFIX='lib'
|
||||
;;
|
||||
esac
|
||||
ifelse($1,,,[$1=$LIB_PREFIX])
|
||||
AC_SUBST(LIB_PREFIX)
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_LIB_RULES version: 50 updated: 2007/03/24 18:26:59
|
||||
dnl CF_LIB_RULES version: 53 updated: 2008/09/20 19:51:59
|
||||
dnl ------------
|
||||
dnl Append definitions and rules for the given models to the subdirectory
|
||||
dnl Makefiles, and the recursion rule for the top-level Makefile. If the
|
||||
@ -2044,6 +2233,12 @@ AC_DEFUN([CF_LIB_RULES],
|
||||
[
|
||||
CF_LIB_PREFIX(cf_prefix)
|
||||
AC_REQUIRE([CF_SUBST_NCURSES_VERSION])
|
||||
|
||||
if test $cf_cv_shlib_version = cygdll ; then
|
||||
TINFO_NAME=$TINFO_ARG_SUFFIX
|
||||
TINFO_SUFFIX=.dll
|
||||
fi
|
||||
|
||||
for cf_dir in $SRC_SUBDIRS
|
||||
do
|
||||
if test ! -d $srcdir/$cf_dir ; then
|
||||
@ -2054,7 +2249,7 @@ do
|
||||
LIBS_TO_MAKE=
|
||||
for cf_item in $cf_LIST_MODELS
|
||||
do
|
||||
CF_LIB_SUFFIX($cf_item,cf_suffix)
|
||||
CF_LIB_SUFFIX($cf_item,cf_suffix,cf_depsuf)
|
||||
if test $cf_item = shared ; then
|
||||
if test "$cf_cv_do_symlinks" = yes ; then
|
||||
case "$cf_cv_shlib_version" in #(vi
|
||||
@ -2096,7 +2291,8 @@ do
|
||||
# use autodetected ${cf_prefix} for import lib and static lib, but
|
||||
# use 'cyg' prefix for shared lib.
|
||||
if test $cf_cv_shlib_version = cygdll ; then
|
||||
LIBS_TO_MAKE="$LIBS_TO_MAKE ../lib/cyg${cf_dir}\${ABI_VERSION}.dll"
|
||||
cf_cygsuf=`echo "$cf_suffix" | sed -e 's/\.dll/\${ABI_VERSION}.dll/'`
|
||||
LIBS_TO_MAKE="$LIBS_TO_MAKE ../lib/cyg${cf_dir}${cf_cygsuf}"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
@ -2106,24 +2302,28 @@ do
|
||||
if test $cf_dir = ncurses ; then
|
||||
cf_subsets="$LIB_SUBSETS"
|
||||
cf_r_parts="$cf_subsets"
|
||||
cf_liblist="$LIBS_TO_MAKE"
|
||||
|
||||
while test -n "$cf_r_parts"
|
||||
do
|
||||
cf_l_parts=`echo "$cf_r_parts" |sed -e 's/ .*$//'`
|
||||
cf_r_parts=`echo "$cf_r_parts" |sed -e 's/^[[^ ]]* //'`
|
||||
if test "$cf_l_parts" != "$cf_r_parts" ; then
|
||||
cf_item=
|
||||
case $cf_l_parts in #(vi
|
||||
*termlib*) #(vi
|
||||
cf_item=`echo $LIBS_TO_MAKE |sed -e s%${LIB_NAME}${LIB_SUFFIX}%${TINFO_LIB_SUFFIX}%g`
|
||||
cf_item=`echo $cf_liblist |sed -e s%${LIB_NAME}${LIB_SUFFIX}%${TINFO_LIB_SUFFIX}%g`
|
||||
;;
|
||||
*ticlib*)
|
||||
cf_item=`echo $LIBS_TO_MAKE |sed -e s%${LIB_NAME}${LIB_SUFFIX}%${TICS_LIB_SUFFIX}%g`
|
||||
cf_item=`echo $cf_liblist |sed -e s%${LIB_NAME}${LIB_SUFFIX}%${TICS_LIB_SUFFIX}%g`
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
LIBS_TO_MAKE="$cf_item $LIBS_TO_MAKE"
|
||||
if test -n "$cf_item"; then
|
||||
LIBS_TO_MAKE="$cf_item $LIBS_TO_MAKE"
|
||||
fi
|
||||
else
|
||||
break
|
||||
fi
|
||||
@ -2148,7 +2348,7 @@ do
|
||||
do
|
||||
echo "Appending rules for ${cf_item} model (${cf_dir}: ${cf_subset})"
|
||||
CF_UPPER(cf_ITEM,$cf_item)
|
||||
CF_LIB_SUFFIX($cf_item,cf_suffix)
|
||||
CF_LIB_SUFFIX($cf_item,cf_suffix,cf_depsuf)
|
||||
CF_OBJ_SUBDIR($cf_item,cf_subdir)
|
||||
|
||||
# Test for case where we build libtinfo with a different name.
|
||||
@ -2156,22 +2356,21 @@ do
|
||||
if test $cf_dir = ncurses ; then
|
||||
case $cf_subset in
|
||||
*base*)
|
||||
cf_libname=${cf_libname}$LIB_SUFFIX
|
||||
;;
|
||||
*termlib*)
|
||||
cf_libname=$TINFO_LIB_SUFFIX
|
||||
if test -n "${DFT_ARG_SUFFIX}" ; then
|
||||
# undo $LIB_SUFFIX add-on in CF_LIB_SUFFIX
|
||||
cf_suffix=`echo $cf_suffix |sed -e "s%^${LIB_SUFFIX}%%"`
|
||||
fi
|
||||
;;
|
||||
ticlib*)
|
||||
cf_libname=$TICS_LIB_SUFFIX
|
||||
if test -n "${DFT_ARG_SUFFIX}" ; then
|
||||
# undo $LIB_SUFFIX add-on in CF_LIB_SUFFIX
|
||||
cf_suffix=`echo $cf_suffix |sed -e "s%^${LIB_SUFFIX}%%"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
else
|
||||
cf_libname=${cf_libname}$LIB_SUFFIX
|
||||
fi
|
||||
if test -n "${DFT_ARG_SUFFIX}" ; then
|
||||
# undo $LIB_SUFFIX add-on in CF_LIB_SUFFIX
|
||||
cf_suffix=`echo $cf_suffix |sed -e "s%^${LIB_SUFFIX}%%"`
|
||||
fi
|
||||
|
||||
# These dependencies really are for development, not
|
||||
@ -2480,34 +2679,62 @@ fi
|
||||
])
|
||||
])
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_LIB_SUFFIX version: 13 updated: 2003/11/01 16:09:07
|
||||
dnl CF_LIB_SUFFIX version: 15 updated: 2008/09/13 11:54:48
|
||||
dnl -------------
|
||||
dnl Compute the library file-suffix from the given model name
|
||||
dnl $1 = model name
|
||||
dnl $2 = variable to set
|
||||
dnl $2 = variable to set (the nominal library suffix)
|
||||
dnl $3 = dependency variable to set (actual filename)
|
||||
dnl The variable $LIB_SUFFIX, if set, prepends the variable to set.
|
||||
AC_DEFUN([CF_LIB_SUFFIX],
|
||||
[
|
||||
AC_REQUIRE([CF_SUBST_NCURSES_VERSION])
|
||||
case $1 in
|
||||
libtool) $2='.la' ;;
|
||||
normal) $2='.a' ;;
|
||||
debug) $2='_g.a' ;;
|
||||
profile) $2='_p.a' ;;
|
||||
libtool)
|
||||
$2='.la'
|
||||
$3=[$]$2
|
||||
;;
|
||||
normal)
|
||||
$2='.a'
|
||||
$3=[$]$2
|
||||
;;
|
||||
debug)
|
||||
$2='_g.a'
|
||||
$3=[$]$2
|
||||
;;
|
||||
profile)
|
||||
$2='_p.a'
|
||||
$3=[$]$2
|
||||
;;
|
||||
shared)
|
||||
case $cf_cv_system_name in
|
||||
cygwin*) $2='.dll' ;;
|
||||
darwin*) $2='.dylib' ;;
|
||||
cygwin*)
|
||||
$2='.dll'
|
||||
$3='.dll.a'
|
||||
;;
|
||||
darwin*)
|
||||
$2='.dylib'
|
||||
$3=[$]$2
|
||||
;;
|
||||
hpux*)
|
||||
case $target in
|
||||
ia64*) $2='.so' ;;
|
||||
*) $2='.sl' ;;
|
||||
ia64*)
|
||||
$2='.so'
|
||||
$3=[$]$2
|
||||
;;
|
||||
*)
|
||||
$2='.sl'
|
||||
$3=[$]$2
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*) $2='.so' ;;
|
||||
*) $2='.so'
|
||||
$3=[$]$2
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
test -n "$LIB_SUFFIX" && $2="${LIB_SUFFIX}[$]{$2}"
|
||||
test -n "$LIB_SUFFIX" && $3="${LIB_SUFFIX}[$]{$3}"
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_LIB_TYPE version: 4 updated: 2000/10/20 22:57:49
|
||||
@ -3869,7 +4096,7 @@ define([CF_REMOVE_LIB],
|
||||
$1=`echo "$2" | sed -e 's/-l$3[[ ]]//g' -e 's/-l$3[$]//'`
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_RPATH_HACK version: 3 updated: 2007/12/01 11:14:13
|
||||
dnl CF_RPATH_HACK version: 4 updated: 2008/09/13 12:53:26
|
||||
dnl -------------
|
||||
AC_DEFUN([CF_RPATH_HACK],
|
||||
[
|
||||
@ -3881,48 +4108,46 @@ CF_VERBOSE(...checking LDFLAGS $LDFLAGS)
|
||||
CF_VERBOSE(...checking EXTRA_LDFLAGS $EXTRA_LDFLAGS)
|
||||
case "$EXTRA_LDFLAGS" in #(vi
|
||||
-Wl,-rpath,*) #(vi
|
||||
cf_rpath_hack="-Wl,-rpath,"
|
||||
;;
|
||||
cf_rpath_hack="-Wl,-rpath,"
|
||||
;;
|
||||
-R\ *)
|
||||
cf_rpath_hack="-R "
|
||||
;;
|
||||
cf_rpath_hack="-R "
|
||||
;;
|
||||
-R*)
|
||||
cf_rpath_hack="-R"
|
||||
;;
|
||||
cf_rpath_hack="-R"
|
||||
;;
|
||||
*)
|
||||
cf_rpath_hack=
|
||||
;;
|
||||
cf_rpath_hack=
|
||||
;;
|
||||
esac
|
||||
if test -n "$cf_rpath_hack" ; then
|
||||
cf_rpath_dst=
|
||||
for cf_rpath_src in $LDFLAGS
|
||||
do
|
||||
CF_VERBOSE(Filtering $cf_rpath_src)
|
||||
case $cf_rpath_src in #(vi
|
||||
-L*) #(vi
|
||||
if test "$cf_rpath_hack" = "-R " ; then
|
||||
cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e 's%-L%-R %'`
|
||||
else
|
||||
cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e s%-L%$cf_rpath_hack%`
|
||||
fi
|
||||
CF_VERBOSE(...Filter $cf_rpath_tmp)
|
||||
EXTRA_LDFLAGS="$cf_rpath_tmp $EXTRA_LDFLAGS"
|
||||
;;
|
||||
*)
|
||||
cf_rpath_dst="$cf_rpath_dst $cf_rpath_src"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
LDFLAGS=$cf_rpath_dst
|
||||
CF_VERBOSE(...checked LDFLAGS $LDFLAGS)
|
||||
CF_VERBOSE(...checked EXTRA_LDFLAGS $EXTRA_LDFLAGS)
|
||||
cf_rpath_dst=
|
||||
for cf_rpath_src in $LDFLAGS
|
||||
do
|
||||
CF_VERBOSE(Filtering $cf_rpath_src)
|
||||
case $cf_rpath_src in #(vi
|
||||
-L*) #(vi
|
||||
if test "$cf_rpath_hack" = "-R " ; then
|
||||
cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e 's%-L%-R %'`
|
||||
else
|
||||
cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e s%-L%$cf_rpath_hack%`
|
||||
fi
|
||||
CF_VERBOSE(...Filter $cf_rpath_tmp)
|
||||
EXTRA_LDFLAGS="$cf_rpath_tmp $EXTRA_LDFLAGS"
|
||||
;;
|
||||
esac
|
||||
cf_rpath_dst="$cf_rpath_dst $cf_rpath_src"
|
||||
done
|
||||
LDFLAGS=$cf_rpath_dst
|
||||
CF_VERBOSE(...checked LDFLAGS $LDFLAGS)
|
||||
CF_VERBOSE(...checked EXTRA_LDFLAGS $EXTRA_LDFLAGS)
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_SHARED_OPTS version: 47 updated: 2008/03/23 14:48:54
|
||||
dnl CF_SHARED_OPTS version: 53 updated: 2008/10/25 18:14:20
|
||||
dnl --------------
|
||||
dnl --------------
|
||||
dnl Attempt to determine the appropriate CC/LD options for creating a shared
|
||||
@ -4057,8 +4282,10 @@ CF_EOF
|
||||
# tested with IRIX 5.2 and 'cc'.
|
||||
if test "$GCC" != yes; then
|
||||
CC_SHARED_OPTS='-KPIC'
|
||||
MK_SHARED_LIB='${CC} -shared -rdata_shared -soname `basename $[@]` -o $[@]'
|
||||
else
|
||||
MK_SHARED_LIB='${CC} -shared -Wl,-soname,`basename $[@]` -o $[@]'
|
||||
fi
|
||||
MK_SHARED_LIB='${CC} -shared -rdata_shared -soname `basename $[@]` -o $[@]'
|
||||
cf_cv_rm_so_locs=yes
|
||||
;;
|
||||
linux*|gnu*|k*bsd*-gnu)
|
||||
@ -4071,13 +4298,22 @@ CF_EOF
|
||||
EXTRA_LDFLAGS="-Wl,-rpath,\${libdir} $EXTRA_LDFLAGS"
|
||||
fi
|
||||
CF_SHARED_SONAME
|
||||
MK_SHARED_LIB='${CC} ${CFLAGS} -shared -Wl,-soname,'$cf_shared_soname',-stats,-lc -o $[@]'
|
||||
MK_SHARED_LIB='${CC} ${CFLAGS} -shared -Wl,-soname,'$cf_cv_shared_soname',-stats,-lc -o $[@]'
|
||||
;;
|
||||
openbsd[[2-9]].*)
|
||||
if test "$DFT_LWR_MODEL" = "shared" ; then
|
||||
LOCAL_LDFLAGS="-Wl,-rpath,\$(LOCAL_LIBDIR)"
|
||||
LOCAL_LDFLAGS2="$LOCAL_LDFLAGS"
|
||||
fi
|
||||
if test "$cf_cv_ld_rpath" = yes ; then
|
||||
cf_ld_rpath_opt="-Wl,-rpath,"
|
||||
EXTRA_LDFLAGS="-Wl,-rpath,\${libdir} $EXTRA_LDFLAGS"
|
||||
fi
|
||||
CC_SHARED_OPTS="$CC_SHARED_OPTS -DPIC"
|
||||
MK_SHARED_LIB='${LD} -Bshareable -soname,`basename $[@].${ABI_VERSION}` -o $[@]'
|
||||
CF_SHARED_SONAME
|
||||
MK_SHARED_LIB='${CC} ${CFLAGS} -Wl,-Bshareable,-soname,'$cf_cv_shared_soname',-stats,-lc -o $[@]'
|
||||
;;
|
||||
openbsd*|freebsd[[12]].*)
|
||||
nto-qnx*|openbsd*|freebsd[[12]].*)
|
||||
CC_SHARED_OPTS="$CC_SHARED_OPTS -DPIC"
|
||||
MK_SHARED_LIB='${LD} -Bshareable -o $[@]'
|
||||
test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel
|
||||
@ -4108,7 +4344,7 @@ CF_EOF
|
||||
fi
|
||||
fi
|
||||
CF_SHARED_SONAME
|
||||
MK_SHARED_LIB='${CC} ${CFLAGS} -shared -Wl,-soname,'$cf_shared_soname' -o $[@]'
|
||||
MK_SHARED_LIB='${CC} ${CFLAGS} -shared -Wl,-soname,'$cf_cv_shared_soname' -o $[@]'
|
||||
else
|
||||
MK_SHARED_LIB='${LD} -Bshareable -o $[@]'
|
||||
fi
|
||||
@ -4158,9 +4394,7 @@ CF_EOF
|
||||
;;
|
||||
solaris2*)
|
||||
# tested with SunOS 5.5.1 (solaris 2.5.1) and gcc 2.7.2
|
||||
if test "$GCC" != yes; then
|
||||
CC_SHARED_OPTS='-KPIC'
|
||||
fi
|
||||
# tested with SunOS 5.10 (solaris 10) and gcc 3.4.3
|
||||
if test "$DFT_LWR_MODEL" = "shared" ; then
|
||||
LOCAL_LDFLAGS="-R \$(LOCAL_LIBDIR):\${libdir}"
|
||||
LOCAL_LDFLAGS2="$LOCAL_LDFLAGS"
|
||||
@ -4170,7 +4404,12 @@ CF_EOF
|
||||
EXTRA_LDFLAGS="$LOCAL_LDFLAGS $EXTRA_LDFLAGS"
|
||||
fi
|
||||
CF_SHARED_SONAME
|
||||
MK_SHARED_LIB='${CC} -dy -G -h '$cf_shared_soname' -o $[@]'
|
||||
if test "$GCC" != yes; then
|
||||
CC_SHARED_OPTS='-xcode=pic32'
|
||||
MK_SHARED_LIB='${CC} -dy -G -h '$cf_cv_shared_soname' -o $[@]'
|
||||
else
|
||||
MK_SHARED_LIB='${CC} -shared -dy -G -h '$cf_cv_shared_soname' -o $[@]'
|
||||
fi
|
||||
;;
|
||||
sysv5uw7*|unix_sv*)
|
||||
# tested with UnixWare 7.1.0 (gcc 2.95.2 and cc)
|
||||
@ -4221,9 +4460,9 @@ CF_EOF
|
||||
AC_SUBST(INSTALL_LIB)
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_SHARED_SONAME version: 2 updated: 2006/10/21 12:33:41
|
||||
dnl CF_SHARED_SONAME version: 3 updated: 2008/09/08 18:34:43
|
||||
dnl ----------------
|
||||
dnl utility macro for CF_SHARED_OPTS, constructs "$cf_shared_soname" for
|
||||
dnl utility macro for CF_SHARED_OPTS, constructs "$cf_cv_shared_soname" for
|
||||
dnl substitution into MK_SHARED_LIB string for the "-soname" (or similar)
|
||||
dnl option.
|
||||
dnl
|
||||
@ -4233,9 +4472,9 @@ define([CF_SHARED_SONAME],
|
||||
[
|
||||
test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=ifelse($1,,rel,$1)
|
||||
if test "$cf_cv_shlib_version" = rel; then
|
||||
cf_shared_soname='`basename $[@] .${REL_VERSION}`.${ABI_VERSION}'
|
||||
cf_cv_shared_soname='`basename $[@] .${REL_VERSION}`.${ABI_VERSION}'
|
||||
else
|
||||
cf_shared_soname='`basename $[@]`'
|
||||
cf_cv_shared_soname='`basename $[@]`'
|
||||
fi
|
||||
])
|
||||
dnl ---------------------------------------------------------------------------
|
||||
@ -4607,6 +4846,22 @@ if test "$ac_cv_header_termios_h" = yes ; then
|
||||
fi
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_SUBDIR_PATH version: 5 updated: 2007/07/29 09:55:12
|
||||
dnl --------------
|
||||
dnl Construct a search-list for a nonstandard header/lib-file
|
||||
dnl $1 = the variable to return as result
|
||||
dnl $2 = the package name
|
||||
dnl $3 = the subdirectory, e.g., bin, include or lib
|
||||
AC_DEFUN([CF_SUBDIR_PATH],
|
||||
[$1=""
|
||||
|
||||
CF_ADD_SUBDIR_PATH($1,$2,$3,/usr,$prefix)
|
||||
CF_ADD_SUBDIR_PATH($1,$2,$3,$prefix,NONE)
|
||||
CF_ADD_SUBDIR_PATH($1,$2,$3,/usr/local,$prefix)
|
||||
CF_ADD_SUBDIR_PATH($1,$2,$3,/opt,$prefix)
|
||||
CF_ADD_SUBDIR_PATH($1,$2,$3,[$]HOME,$prefix)
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_SUBST version: 4 updated: 2006/06/17 12:33:03
|
||||
dnl --------
|
||||
dnl Shorthand macro for substituting things that the user may override
|
||||
@ -4793,6 +5048,32 @@ AC_DEFUN([CF_UPPER],
|
||||
$1=`echo "$2" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_UTF8_LIB version: 5 updated: 2008/10/17 19:37:52
|
||||
dnl -----------
|
||||
dnl Check for multibyte support, and if not found, utf8 compatibility library
|
||||
AC_DEFUN([CF_UTF8_LIB],
|
||||
[
|
||||
AC_CACHE_CHECK(for multibyte character support,cf_cv_utf8_lib,[
|
||||
cf_save_LIBS="$LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdlib.h>],[putwc(0,0);],
|
||||
[cf_cv_utf8_lib=yes],
|
||||
[CF_FIND_LINKAGE([
|
||||
#include <libutf8.h>],[putwc(0,0);],utf8,
|
||||
[cf_cv_utf8_lib=add-on],
|
||||
[cf_cv_utf8_lib=no])
|
||||
])])
|
||||
|
||||
# HAVE_LIBUTF8_H is used by ncurses if curses.h is shared between
|
||||
# ncurses/ncursesw:
|
||||
if test "$cf_cv_utf8_lib" = "add-on" ; then
|
||||
AC_DEFINE(HAVE_LIBUTF8_H)
|
||||
CF_ADD_INCDIR($cf_cv_header_path_utf8)
|
||||
CF_ADD_LIBDIR($cf_cv_library_path_utf8)
|
||||
LIBS="-lutf8 $LIBS"
|
||||
fi
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_VERBOSE version: 3 updated: 2007/07/29 09:55:12
|
||||
dnl ----------
|
||||
dnl Use AC_VERBOSE w/o the warnings
|
||||
@ -4851,6 +5132,32 @@ fi
|
||||
])
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_WEAK_SYMBOLS version: 1 updated: 2008/08/16 19:18:06
|
||||
dnl ---------------
|
||||
dnl Check for compiler-support for weak symbols.
|
||||
dnl This works with "recent" gcc.
|
||||
AC_DEFUN([CF_WEAK_SYMBOLS],[
|
||||
AC_CACHE_CHECK(if $CC supports weak symbols,cf_cv_weak_symbols,[
|
||||
|
||||
AC_TRY_COMPILE([
|
||||
#include <stdio.h>],
|
||||
[
|
||||
#if defined(__GNUC__)
|
||||
# if defined __USE_ISOC99
|
||||
# define _cat_pragma(exp) _Pragma(#exp)
|
||||
# define _weak_pragma(exp) _cat_pragma(weak name)
|
||||
# else
|
||||
# define _weak_pragma(exp)
|
||||
# endif
|
||||
# define _declare(name) __extension__ extern __typeof__(name) name
|
||||
# define weak_symbol(name) _weak_pragma(name) _declare(name) __attribute__((weak))
|
||||
#endif
|
||||
|
||||
weak_symbol(fopen);
|
||||
],[cf_cv_weak_symbols=yes],[cf_cv_weak_symbols=no])
|
||||
])
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_WITH_ABI_VERSION version: 1 updated: 2003/09/20 18:12:49
|
||||
dnl -------------------
|
||||
dnl Allow library's ABI to be overridden. Generally this happens when a
|
||||
@ -5128,7 +5435,7 @@ AC_SUBST($3)dnl
|
||||
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_WITH_PTHREAD version: 1 updated: 2008/03/29 13:42:21
|
||||
dnl CF_WITH_PTHREAD version: 2 updated: 2008/08/23 18:26:05
|
||||
dnl ---------------
|
||||
dnl Check for POSIX thread library.
|
||||
AC_DEFUN([CF_WITH_PTHREAD],
|
||||
@ -5143,13 +5450,24 @@ AC_MSG_RESULT($with_pthread)
|
||||
if test "$with_pthread" != no ; then
|
||||
AC_CHECK_HEADER(pthread.h,[
|
||||
AC_DEFINE(HAVE_PTHREADS_H)
|
||||
AC_CHECK_LIB(pthread,pthread_create,[
|
||||
|
||||
AC_MSG_CHECKING(if we can link with the pthread library)
|
||||
cf_save_LIBS="$LIBS"
|
||||
LIBS="-lpthread $LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <pthread.h>
|
||||
],[
|
||||
int rc = pthread_create(0,0,0,0);
|
||||
],[with_pthread=yes],[with_pthread=no])
|
||||
LIBS="$cf_save_LIBS"
|
||||
AC_MSG_RESULT($with_pthread)
|
||||
|
||||
if test "$with_pthread" = yes ; then
|
||||
LIBS="-lpthread $LIBS"
|
||||
AC_DEFINE(HAVE_LIBPTHREADS)
|
||||
with_pthread=yes
|
||||
],[
|
||||
else
|
||||
AC_MSG_ERROR(Cannot link with pthread library)
|
||||
])
|
||||
fi
|
||||
])
|
||||
fi
|
||||
])
|
||||
@ -5217,7 +5535,7 @@ CF_NO_LEAKS_OPTION(valgrind,
|
||||
[USE_VALGRIND])
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_XOPEN_SOURCE version: 25 updated: 2007/01/29 18:36:38
|
||||
dnl CF_XOPEN_SOURCE version: 26 updated: 2008/07/27 11:26:57
|
||||
dnl ---------------
|
||||
dnl Try to get _XOPEN_SOURCE defined properly that we can use POSIX functions,
|
||||
dnl or adapt to the vendor's definitions to get equivalent functionality,
|
||||
@ -5237,7 +5555,7 @@ case $host_os in #(vi
|
||||
aix[[45]]*) #(vi
|
||||
CPPFLAGS="$CPPFLAGS -D_ALL_SOURCE"
|
||||
;;
|
||||
freebsd*) #(vi
|
||||
freebsd*|dragonfly*) #(vi
|
||||
# 5.x headers associate
|
||||
# _XOPEN_SOURCE=600 with _POSIX_C_SOURCE=200112L
|
||||
# _XOPEN_SOURCE=500 with _POSIX_C_SOURCE=199506L
|
||||
|
@ -1,8 +1,8 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
|
||||
<!--
|
||||
$Id: announce.html.in,v 1.64 2006/12/17 23:31:26 tom Exp $
|
||||
$Id: announce.html.in,v 1.70 2008/11/02 01:03:05 tom Exp $
|
||||
****************************************************************************
|
||||
* Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. *
|
||||
* Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the *
|
||||
@ -69,185 +69,170 @@ the GNU distribution site
|
||||
|
||||
<H1>Release Notes</H1>
|
||||
|
||||
This release is designed to be upward compatible from ncurses 5.0 through 5.5;
|
||||
This release is designed to be upward compatible from ncurses 5.0 through 5.6;
|
||||
very few applications will require recompilation, depending on the platform.
|
||||
These are the highlights from the change-log since ncurses 5.5 release.
|
||||
These are the highlights from the change-log since ncurses 5.6 release.
|
||||
<p>
|
||||
Interface changes:
|
||||
<ul>
|
||||
<li>generate linkable stubs for some macros:
|
||||
<br>
|
||||
getbegx, getbegy, getcurx, getcury, getmaxx, getmaxy, getparx,
|
||||
getpary, getpary,
|
||||
<br>
|
||||
and (for libncursesw)
|
||||
<br>
|
||||
wgetbkgrnd
|
||||
getattrs
|
||||
|
||||
</ul>
|
||||
New features and improvements:
|
||||
<ul>
|
||||
<li>library
|
||||
<ul>
|
||||
<li>support hashed databases for the terminal descriptions.
|
||||
This uses the Berkeley database, has been tested for
|
||||
several versions on different platforms.
|
||||
<li>new flavor of the ncurses library provides rudimentary
|
||||
support for POSIX threads. Several functions are
|
||||
reentrant, but most require either a window-level or
|
||||
screen-level mutex.<br>
|
||||
(This is <em>API</em>-compatible,
|
||||
but not <em>ABI</em>-compatible with the normal library).
|
||||
|
||||
<li>add <code>use_legacy_coding()</code> function to support
|
||||
lynx's font-switching feature.
|
||||
<li>add <code>NCURSES_OPAQUE</code> symbol to curses.h, will
|
||||
use to make structs opaque in selected configurations.
|
||||
|
||||
<li>add extension <code>nofilter()</code>, to cancel a prior
|
||||
<code>filter()</code> call.
|
||||
<li>add <code>NCURSES_EXT_FUNCS</code> and
|
||||
<code>NCURSES_EXT_COLORS</code> symbols to curses.h to make
|
||||
it simpler to tell if the extended functions and/or colors
|
||||
are declared.
|
||||
|
||||
<li>add/install a package config script, e.g.,
|
||||
<code>ncurses5-config</code> or
|
||||
<code>ncursesw5-config</code>, according to
|
||||
configuration options.
|
||||
<li>add wresize() to C++ binding
|
||||
|
||||
<li>provide ifdef for <code>NCURSES_NOMACROS</code> which
|
||||
suppresses most macro definitions from curses.h, i.e.,
|
||||
where a macro is defined to override a function to improve
|
||||
performance.
|
||||
<li>eliminate fixed-buffer vsprintf() calls in C++ binding.
|
||||
|
||||
<li>make ifdef's consistent in <code>curses.h</code> for the
|
||||
extended colors so the header file can be used for the
|
||||
normal curses library. The header file installed for
|
||||
extended colors is a variation of the wide-character
|
||||
configuration.
|
||||
<li>add several functions to C++ binding which wrap C functions
|
||||
that pass a WINDOW* parameter.
|
||||
|
||||
<li>improve <code>tgetstr()</code> by making the return value
|
||||
point into the user's buffer, if provided.
|
||||
<li>adapt mouse-handling code from menu library in form-library
|
||||
|
||||
<li>add ifdef's allowing ncurses to be built with
|
||||
<code>tparm()</code> using either varargs (the existing
|
||||
status), or using a fixed-parameter list (to match X/Open).
|
||||
<li>improve tracing for form library, showing created forms,
|
||||
fields, etc.
|
||||
|
||||
<li>widen the test for xterm <code>kmous</code> a little to
|
||||
<code>allow</code> for other
|
||||
strings than "\E[M", e.g., for <code>xterm-sco</code>
|
||||
functionality in xterm.
|
||||
<li>make $NCURSES_NO_PADDING feature work for termcap interface .
|
||||
|
||||
<li>modify <code>wgetnstr()</code> to return
|
||||
<code>KEY_RESIZE</code> if a sigwinch occurs.
|
||||
<li>add check to trace-file open, if the given name is a
|
||||
directory, add ".log" to the name and try again.
|
||||
|
||||
<li>move prototypes for wide-character trace functions from
|
||||
curses.tail to curses.wide to avoid accidental reference to
|
||||
those if <code>_XOPEN_SOURCE_EXTENDED</code> is defined
|
||||
without ensuring that <wchar.h> is included.
|
||||
|
||||
<li>change the way shared libraries (other than libtool) are
|
||||
installed. Rather than copying the build-tree's libraries,
|
||||
link the shared objects into the install directory. This
|
||||
makes the <code>--with-rpath</code> option work except with
|
||||
<code>$(DESTDIR)</code>.
|
||||
|
||||
<li>several improvements for rendering in hpterm. These are
|
||||
only available if the library is configured using
|
||||
<code>--enable-xmc-glitch</code>.
|
||||
|
||||
<li>Add <code>NCURSES_NO_HARD_TABS</code> and
|
||||
<code>NCURSES_NO_MAGIC_COOKIE</code> environment variables
|
||||
to allow runtime suppression of the related hard-tabs and
|
||||
xmc-glitch features.
|
||||
<li>several new manpages: curs_legacy.3x, curs_memleaks.3x,
|
||||
curs_opaque.3x and curs_threads.3x
|
||||
</ul>
|
||||
|
||||
<li>programs:
|
||||
<ul>
|
||||
<li>add new test programs: chgat.c, demo_altkeys.c,
|
||||
echochar.c, foldkeys.c, movewindow.c, redraw.c, (noting
|
||||
that existing test programs also were modified to test
|
||||
additional features).
|
||||
<li>modified three test-programs to demonstrate the threading
|
||||
support in this version: ditto, rain, worm.
|
||||
|
||||
<li>modify tack to test extended capability function-key
|
||||
strings.
|
||||
<li>several new test-programs: demo_panels, dots_mvcur,
|
||||
inch_wide, inchs, key_name, key_names, savescreen,
|
||||
savescreen.sh test_arrays, test_get_wstr, test_getstr,
|
||||
test_instr, test_inwstr and test_opaque.
|
||||
|
||||
<li>modify toe to access termcap data, e.g., via <code>cgetent()</code>
|
||||
functions, or as a text file if those are not available.
|
||||
<li>add <code>adacurses-config</code> to the Ada95 install.
|
||||
|
||||
<li>improve infocmp/tic <code>-f</code> option formatting.
|
||||
<li>modify tic <code>-f</code> option to format spaces as
|
||||
<code>\s</code> to prevent them from being lost when that
|
||||
is read back in unformatted strings.
|
||||
|
||||
<li>add <code>toe -a</code> option, to show all databases.
|
||||
This uses new private interfaces in the ncurses library for
|
||||
iterating through the list of databases.
|
||||
|
||||
<li>modify <code>MKfallback.sh</code> to use
|
||||
<code>tic -x</code> when constructing fallback tables to
|
||||
allow extended capabilities to be retrieved from a fallback entry.
|
||||
<li>The <code>tack</code> program is now distributed separately
|
||||
from ncurses.
|
||||
</ul>
|
||||
|
||||
<li>terminal database
|
||||
<ul>
|
||||
<li>add terminfo entries for xfce terminal (xfce) and multi gnome terminal (mgt)
|
||||
<li>add nsterm-16color entry
|
||||
<li>updated mlterm terminfo entry
|
||||
<li>add kon, kon2 and jfbterm terminfo entry
|
||||
<li>remove invis capability from klone+sgr, mainly used by linux entry, since it does not really do this
|
||||
<li>add ka2, kb1, kb3, kc2 to vt220-keypad as an extension
|
||||
<li>add shifted up/down arrow codes to xterm-new as kind/kri strings
|
||||
<li>add hpterm-color terminfo entry
|
||||
<li>add 256color variants of terminfo entries for programs which are reported to implement this feature
|
||||
<li>correct order of use-clauses in rxvt-basic entry which made codes for f1-f4 vt100-style rather than vt220-style.
|
||||
<li>added entries:
|
||||
<ul>
|
||||
<li><code>Eterm-256color</code>,
|
||||
<code>Eterm-88color</code> and
|
||||
<code>rxvt-88color</code>
|
||||
<li><code>aterm</code>
|
||||
<li><code>konsole-256color</code>
|
||||
<li><code>mrxvt</code>
|
||||
<li><code>screen.mlterm</code>
|
||||
<li><code>screen.rxvt</code>
|
||||
<li><code>teraterm4.59</code> is now the primary primary
|
||||
teraterm entry, renamed original to
|
||||
<code>teraterm2.3</code>
|
||||
<li><code>9term</code> terminal
|
||||
<li>Newbury Data entries
|
||||
</ul>
|
||||
<li>updated/improved entries:
|
||||
<ul>
|
||||
<li><code>gnome</code> to version 2.22.3
|
||||
<li><code>h19</code>, <code>z100</code>
|
||||
<li><code>konsole</code> to version 1.6.6
|
||||
<li><code>mlterm</code>, <code>mlterm+pcfkeys</code>
|
||||
<li><code>xterm</code>, and building-blocks for function-keys
|
||||
to <a href="http://invisible-island.net/xterm/xterm.log.html#xterm_230">xterm patch #230</a>.
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
Major bug fixes:
|
||||
<ul>
|
||||
<li>correct a typo in configure <code>--with-bool</code> option for the
|
||||
case where <code>--without-cxx</code> is used.
|
||||
<li>add logic to tic for cancelling strings in user-defined
|
||||
capabilities
|
||||
(this is <em>needed</em> for
|
||||
current <code>konsole</code> terminfo entry).
|
||||
|
||||
<li>move assignment from environment variable <code>ESCDELAY</code>
|
||||
from <code>initscr()</code> down to <code>newterm()</code> so the
|
||||
environment variable affects timeouts for terminals opened with
|
||||
newterm() as well.
|
||||
<li>modify <code>mk-1st.awk</code> so the generated makefile rules for
|
||||
linking or installing shared libraries do not first remove the
|
||||
library, in case it is in use, e.g., <code>libncurses.so</code> by
|
||||
<code>/bin/sh</code>.
|
||||
|
||||
<li>modify <code>werase</code> to clear multicolumn characters that
|
||||
extend into a derived window.
|
||||
<li>correct check for notimeout() in wgetch().
|
||||
|
||||
<li>modify <code>wchgat()</code> to mark updated cells as changed so a
|
||||
refresh will repaint those cells.
|
||||
<li>fix a sign-extension bug in infocmp's repair_acsc() function.
|
||||
|
||||
<li>correct logic in <code>wadd_wch()</code> and
|
||||
<code>wecho_wch()</code>, which did not guard against passing the
|
||||
multi-column attribute into a call on <code>waddch()</code>, e.g.,
|
||||
using data returned by <code>win_wch()</code>
|
||||
<li>change winnstr() to stop at the end of the line.
|
||||
|
||||
<li>fix redrawing of windows other than <code>stdscr</code> using
|
||||
<code>wredrawln()</code> by touching the corresponding rows in
|
||||
<code>curscr</code>.
|
||||
<li>make Ada95 demo_panels() example work.
|
||||
|
||||
<li>reduce memory leaks in repeated calls to <code>tgetent()</code> by
|
||||
remembering the last <code>TERMINAL*</code> value allocated to hold
|
||||
the corresponding data and freeing that if the
|
||||
<code>tgetent()</code> result buffer is the same as the previous
|
||||
call.
|
||||
<li>fix for adding a non-spacing character at the beginning of a line.
|
||||
|
||||
<li>modify <code>read_termtype()</code> so the <code>term_names</code>
|
||||
data is always allocated as part of the <code>str_table</code>, a
|
||||
better fix for a memory leak.
|
||||
<li>fill in extended-color pair to make colors work
|
||||
for wide-characters using extended-colors.
|
||||
|
||||
<li>fix <code>wins_nwstr(),</code> which did not handle single-column
|
||||
non-8bit codes.
|
||||
<li>improve refresh of window on top of multi-column characters,
|
||||
taking into account split characters on left/right window
|
||||
boundaries.
|
||||
|
||||
<li>modify <code>wbkgrnd()</code> to avoid clearing the
|
||||
<code>A_CHARTEXT</code> attribute bits since those record the state
|
||||
of multicolumn characters.
|
||||
<li>modify <code>win_wchnstr()</code> to ensure that only a base cell
|
||||
is returned for each multi-column character.
|
||||
|
||||
<li>improve <code>SIGWINCH</code> handling by postponing its effect
|
||||
during <code>newterm()</code>, etc., when allocating screens.
|
||||
<li>improve <code>waddch()</code> and <code>winsch()</code> handling of
|
||||
EILSEQ from <code>mbrtowc()</code> by using <code>unctrl()</code>
|
||||
to display illegal bytes rather than trying to append further bytes
|
||||
to make up a valid sequence.
|
||||
|
||||
<li>remove 970913 feature for copying subwindows as they are moved in
|
||||
<code>mvwin()</code>.
|
||||
<li>restore <code>curs_set()</code> state after
|
||||
<code>endwin()</code>/<code>refresh()</code>
|
||||
|
||||
<li>add checks in <code>waddchnstr()</code> and
|
||||
<code>wadd_wchnstr()</code> to stop copying when a null character
|
||||
is found.
|
||||
<li>modify <code>keyname()</code> to use "^X" form only if
|
||||
<code>meta()</code> has been called, or if <code>keyname()</code>
|
||||
is called without initializing curses, e.g., via
|
||||
<code>initscr()</code> or <code>newterm()</code>.
|
||||
|
||||
<li>add some checks to ensure current position is within scrolling
|
||||
region before scrolling on a new line.
|
||||
<li>modify <code>unctrl()</code> to check codes in 128-255 range versus
|
||||
<code>isprint()</code>.
|
||||
If they are not printable, and locale was set, use a "M-" or "~"
|
||||
sequence.
|
||||
|
||||
<li>add a workaround to ACS mapping to allow applications such as
|
||||
test/blue.c to use the "PC ROM" characters by masking them with
|
||||
A_ALTCHARSET. This worked up til 5.5, but was lost in the revision
|
||||
of legacy coding.
|
||||
<li>improve <code>resizeterm()</code> by moving ripped-off lines, and
|
||||
repainting the soft-keys.
|
||||
|
||||
<li>modify form library to accept control characters such as newline
|
||||
in set_field_buffer(), which is compatible with Solaris.
|
||||
|
||||
<li>use <code>NCURSES_MOUSE_MASK()</code> in definition of
|
||||
<code>BUTTON_RELEASE()</code>, etc., to make those work properly
|
||||
with the <code>--enable-ext-mouse</code> configuration
|
||||
|
||||
<li>correct some functions in Ada95 binding which were using return
|
||||
value from C where none was returned.
|
||||
|
||||
<li>reviewed/fixed issues reported by Coverity and Klocwork tools.
|
||||
</ul>
|
||||
|
||||
Portability:
|
||||
@ -257,110 +242,115 @@ Portability:
|
||||
<li>new options:
|
||||
<dl>
|
||||
|
||||
<dt>--with-hashed-db
|
||||
<dd>Use Berkeley hashed database for storing terminfo data rather than storing
|
||||
each compiled entry in a separate binary file within a directory
|
||||
tree.
|
||||
<dt>--disable-big-strings
|
||||
<dd>control whether static string tables are generated as single
|
||||
large strings (to improve startup performance), or as array
|
||||
of individual strings.
|
||||
|
||||
<dt>--without-dlsym
|
||||
<dd>Do not use <code>dlsym()</code> to load GPM dynamically.
|
||||
<dt>--disable-relink
|
||||
<dd>control whether shared libraries are relinked (during install)
|
||||
when rpath is enabled.
|
||||
|
||||
<dt>--with-valgrind
|
||||
<dd>Simplify building for testing with valgrind.
|
||||
<dt>--disable-tic-depends
|
||||
<dd>make explicit whether tic library depends on ncurses/ncursesw
|
||||
library.
|
||||
|
||||
<dt>--enable-wgetch-events
|
||||
<dd>Compile with experimental wgetch-events code.
|
||||
<dt>--enable-mixed-case
|
||||
<dd>override the configure script's check if the filesystem
|
||||
supports mixed-case filenames.
|
||||
This allows one to control how the terminal database
|
||||
maps to the filesystem.
|
||||
For filesystems that do not support mixed-case, the library
|
||||
uses generate 2-character (hexadecimal) codes for the
|
||||
lower-level of the filesystem terminfo database
|
||||
|
||||
<dt>--enable-signed-char
|
||||
<dd>Store booleans in "signed char" rather than "char".
|
||||
<dt>--enable-reentrant
|
||||
<dd>builds a different flavor of the ncurses library (ncursest)
|
||||
which improves reentrant use of the
|
||||
library by reducing global and static variables
|
||||
(see the "--with-pthread" option for the threaded support).
|
||||
|
||||
<dt>--enable-weak-symbols
|
||||
<dd>use weak-symbols for linking to the POSIX thread library,
|
||||
and use the same soname for the ncurses shared library
|
||||
as the normal library (caveat: the ABI is for the threaded
|
||||
library, which makes global data accessed via functions).
|
||||
|
||||
<dt>--with-pthread
|
||||
<dd>build with the POSIX thread library (tested with AIX,
|
||||
Linux, FreeBSD, OpenBSD, HPUX, IRIX64, Solaris, Tru64).
|
||||
|
||||
<dt>--with-ticlib
|
||||
<dd>build/install the tic-support functions in a separate library
|
||||
|
||||
</dl>
|
||||
|
||||
<li>improved options:
|
||||
<dl>
|
||||
|
||||
<dt>--disable-largefile
|
||||
<dd>make the option work both ways.
|
||||
<dt>--enable-ext-colors
|
||||
<dd>requires the wide-character configuration.
|
||||
|
||||
<dt>--with-gpm
|
||||
<dd>The option now accepts a parameter,
|
||||
i.e., the name of the dynamic GPM library to load via
|
||||
<code>dlopen()</code>
|
||||
<dt>--with-chtype
|
||||
<dd>ignore option value "unsigned" is always added to
|
||||
the type in curses.h; do the same for --with-mmask-t.
|
||||
|
||||
<dt>--disable-symlinks
|
||||
<dd>The option now allows one to
|
||||
disable <code>symlink()</code> in <code>tic</code> even when
|
||||
<code>link()</code> does not work.
|
||||
<dt>--with-dmalloc
|
||||
<dd>build-fix for redefinition of <code>strndup</code>.
|
||||
|
||||
<dt>--with-hashed-db
|
||||
<dd>accepts a parameter which is the install-prefix of a given
|
||||
Berkeley Database.
|
||||
|
||||
<dt>--with-hashed-db
|
||||
<dd>the $LIBS environment variable overrides the search for the db
|
||||
library.
|
||||
|
||||
<dt>--without-hashed-db
|
||||
<dd>assumed when "--disable-database" is used.
|
||||
|
||||
</dl>
|
||||
|
||||
</ul>
|
||||
|
||||
<li>other configure/build issues: <ul> <li>remove special case for
|
||||
Darwin in <code>CF_XOPEN_SOURCE</code> configure macro.
|
||||
|
||||
<li>add configure check to ensure that <code>SIGWINCH</code> is
|
||||
defined on platforms such as OS X which exclude that when
|
||||
<code>_XOPEN_SOURCE,</code> etc., are defined
|
||||
|
||||
<li>use ld's <code>-search_paths_first</code> option on Darwin
|
||||
to work around odd search rules on that platform.
|
||||
|
||||
<li>improve ifdef's for <code>_POSIX_VDISABLE</code> in tset to
|
||||
work with Mac OS X.
|
||||
|
||||
<li>modify configure script to ensure that if the C compiler is
|
||||
used rather than the loader in making shared libraries, the
|
||||
<code>$(CFLAGS)</code> variable is also used.
|
||||
|
||||
<li>use <code>${CC}</code> rather than <code>${LD}</code> in
|
||||
shared library rules for IRIX64, Solaris to help ensure
|
||||
that initialization sections are provided for extra linkage
|
||||
requirements, e.g., of C++ applications.
|
||||
|
||||
<li>improve some shared-library configure scripting for Linux,
|
||||
FreeBSD and NetBSD to make
|
||||
<code>--with-shlib-version</code> work.
|
||||
|
||||
<li>split up dependency of <code>names.c</code> and
|
||||
<code>codes.c</code> in <code>ncurses/Makefile</code> to
|
||||
work with parallel make.
|
||||
|
||||
<li>modify <code>MKlib_gen.sh</code> to change
|
||||
preprocessor-expanded <code>_Bool</code> back to <code>bool</code>.
|
||||
|
||||
<li>modify <code>progs/Makefile.in</code> to make
|
||||
<code>tput init</code> work properly with cygwin,
|
||||
i.e., do not pass a <code>.exe</code> in the reference
|
||||
string used in check_aliases.
|
||||
<li>other configure/build issues:
|
||||
<ul>
|
||||
<li>build-fixes for LynxOS
|
||||
<li>modify shared-library rules to allow FreeBSD 3.x to use rpath.
|
||||
<li>build-fix for FreeBSD "contemporary" TTY interface.
|
||||
<li>build-fixes for AIX with libtool.
|
||||
<li>build-fixes for Darwin and libtool.
|
||||
<li>modify BeOS-specific ifdef's to build on Haiku.
|
||||
<li>corrected gcc options for building shared libraries on Solaris
|
||||
and IRIX64.
|
||||
<li>change shared-library configuration for OpenBSD, make rpath work.
|
||||
<li>build-fixes for using libutf8, e.g., on OpenBSD 3.7
|
||||
<li>add "-e" option in ncurses/Makefile.in when generating source-files
|
||||
to force earlier exit if the build environment fails unexpectedly.
|
||||
<li>add support for shared libraries for QNX.
|
||||
<li>change delimiter in <code>MKlib_gen.sh</code> from '%' to '@', to
|
||||
avoid substitution by IBM xlc to '#' as part of its extensions to
|
||||
digraphs.
|
||||
</ul>
|
||||
|
||||
<li>library:
|
||||
<ul>
|
||||
<li>ignore wide-acs line-drawing characters that
|
||||
<code>wcwidth()</code> claims are not one-column. This is
|
||||
a workaround for Solaris' broken locale support.
|
||||
|
||||
<li>reduce name-pollution in <code>term.h</code> by removing
|
||||
<code>#define</code>'s for HAVE_xxx symbols.
|
||||
|
||||
<li>fix <code>#ifdef</code> in <code>c++/internal.h</code> for
|
||||
QNX 6.1
|
||||
<li>rewrite wrapper for <code>wcrtomb()</code>, making it work on
|
||||
Solaris. This is used in the form library to determine the length
|
||||
of the buffer needed by <code>field_buffer</code>.
|
||||
<li>add/use configure script macro CF_SIG_ATOMIC_T, use the corresponding
|
||||
type for data manipulated by signal handlers.
|
||||
<li>set locale in misc/ncurses-config.in since it uses a range
|
||||
<li>disable GPM mouse support when $TERM does not happen to contain
|
||||
"linux", since Gpm_Open() no longer limits its assertion to terminals
|
||||
that it might handle, e.g., within "screen" in xterm.
|
||||
<li>reset mouse file-descriptor when unloading GPM library.
|
||||
</ul>
|
||||
|
||||
<li>test programs: <ul> <li>modify <code>test/configure</code> script
|
||||
to allow building test programs with PDCurses/X11.
|
||||
|
||||
<li>modified test programs to allow some to work with NetBSD
|
||||
curses. Several do not because NetBSD curses implements a
|
||||
subset of X/Open curses, and also lacks much of SVr4
|
||||
additions. But it is enough for comparison.
|
||||
|
||||
<li>improved <code>test/configure</code> to build test/ncurses
|
||||
on HPUX 11 using the vendor curses.
|
||||
|
||||
<li>change configure script to produce
|
||||
<code>test/Makefile</code> from data file.
|
||||
<li>test programs:
|
||||
<ul>
|
||||
<li>update test programs to build/work with various UNIX curses for
|
||||
comparisons.
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
@ -410,6 +400,8 @@ and <CODE>define_key()</CODE> allow
|
||||
you to better control the use of function keys,
|
||||
e.g., disabling the ncurses KEY_MOUSE,
|
||||
or by defining more than one control sequence to map to a given key code.
|
||||
<LI>Support for 256-color terminals, such as modern xterm, when configured
|
||||
using the <code>--enable-ext-colors</code> option.
|
||||
<LI>Support for 16-color terminals, such as aixterm and modern xterm.
|
||||
<LI>Better cursor-movement optimization. The package now features a
|
||||
cursor-local-movement computation more efficient than either BSD's
|
||||
@ -513,14 +505,10 @@ for similar applications on GNU/Linux.
|
||||
<br>
|
||||
<DT> pinfo
|
||||
<DD> Lynx-like info browser.
|
||||
<A HREF="http://dione.ids.pl/~pborys/software/pinfo/">http://dione.ids.pl/~pborys/software/pinfo/</A>
|
||||
<A HREF="https://alioth.debian.org/projects/pinfo/">https://alioth.debian.org/projects/pinfo/</A>
|
||||
<DT> tin
|
||||
<DD> newsreader, supporting color, MIME
|
||||
<A HREF="http://www.tin.org/">http://www.tin.org/</A>
|
||||
<DT> vh-1.6
|
||||
<DD> Volks-Hypertext browser for the Jargon File
|
||||
<br>
|
||||
<A HREF="http://www.debian.org/Packages/unstable/text/vh.html">http://www.debian.org/Packages/unstable/text/vh.html</A>
|
||||
</DL>
|
||||
as well as some that use ncurses for the terminfo support alone:
|
||||
<DL>
|
||||
|
156
contrib/ncurses/config.guess
vendored
156
contrib/ncurses/config.guess
vendored
@ -4,7 +4,7 @@
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2008-03-12'
|
||||
timestamp='2008-04-14'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@ -180,7 +180,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
os=netbsd
|
||||
os=netbsd
|
||||
;;
|
||||
esac
|
||||
# The OS release
|
||||
@ -219,11 +219,11 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
exit ;;
|
||||
alpha:OSF1:*:*)
|
||||
case $UNAME_RELEASE in
|
||||
*4.0)
|
||||
*4.0)
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
;;
|
||||
*5.*)
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
*5.*)
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
;;
|
||||
esac
|
||||
# According to Compaq, /usr/sbin/psrinfo has been available on
|
||||
@ -295,7 +295,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
echo s390-ibm-zvmoe
|
||||
exit ;;
|
||||
*:OS400:*:*)
|
||||
echo powerpc-ibm-os400
|
||||
echo powerpc-ibm-os400
|
||||
exit ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
@ -375,23 +375,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# MiNT. But MiNT is downward compatible to TOS, so this should
|
||||
# be no problem.
|
||||
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
exit ;;
|
||||
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
m68k:machten:*:*)
|
||||
echo m68k-apple-machten${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@ -461,8 +461,8 @@ EOF
|
||||
echo m88k-motorola-sysv3
|
||||
exit ;;
|
||||
AViiON:dgux:*:*)
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
|
||||
then
|
||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
|
||||
@ -575,8 +575,8 @@ EOF
|
||||
9000/[678][0-9][0-9])
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||
532) # CPU_PA_RISC2_0
|
||||
@ -711,22 +711,22 @@ EOF
|
||||
exit ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
||||
echo c34-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
||||
echo c38-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||
echo c4-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
CRAY*Y-MP:*:*:*)
|
||||
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit ;;
|
||||
@ -750,14 +750,14 @@ EOF
|
||||
exit ;;
|
||||
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
||||
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
5000:UNIX_System_V:4.*:*)
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
@ -785,14 +785,14 @@ EOF
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
i*:windows32*:*)
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
exit ;;
|
||||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit ;;
|
||||
*:Interix*:[3456]*)
|
||||
case ${UNAME_MACHINE} in
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@ -800,8 +800,8 @@ EOF
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
IA64)
|
||||
echo ia64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo ia64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
esac ;;
|
||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
@ -837,7 +837,8 @@ EOF
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null | grep -q __ARM_EABI__
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
else
|
||||
@ -854,7 +855,7 @@ EOF
|
||||
echo crisv32-axis-linux-gnu
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo frv-unknown-linux-gnu
|
||||
echo frv-unknown-linux-gnu
|
||||
exit ;;
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
@ -882,10 +883,10 @@ EOF
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
mips64:Linux:*:*)
|
||||
@ -905,15 +906,15 @@ EOF
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
or32:Linux:*:*)
|
||||
echo or32-unknown-linux-gnu
|
||||
exit ;;
|
||||
echo or32-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
exit ;;
|
||||
@ -929,7 +930,7 @@ EOF
|
||||
EV6) UNAME_MACHINE=alphaev6 ;;
|
||||
EV67) UNAME_MACHINE=alphaev67 ;;
|
||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||
esac
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
|
||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||||
@ -949,7 +950,7 @@ EOF
|
||||
echo ${UNAME_MACHINE}-ibm-linux
|
||||
exit ;;
|
||||
sh64*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
sh*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
@ -964,7 +965,7 @@ EOF
|
||||
echo x86_64-unknown-linux-gnu
|
||||
exit ;;
|
||||
xtensa*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
@ -977,16 +978,13 @@ EOF
|
||||
s/.*supported targets: *//
|
||||
s/ .*//
|
||||
p'`
|
||||
case "$ld_supported_targets" in
|
||||
case "$ld_supported_targets" in
|
||||
elf32-i386)
|
||||
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
|
||||
;;
|
||||
a.out-i386-linux)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
|
||||
exit ;;
|
||||
coff-i386)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
|
||||
exit ;;
|
||||
"")
|
||||
# Either a pre-BFD a.out linker (linux-gnuoldld) or
|
||||
# one that does not give us useful --help.
|
||||
@ -1019,10 +1017,10 @@ EOF
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^LIBC/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
/^LIBC/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${LIBC}" != x && {
|
||||
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||||
exit
|
||||
@ -1036,11 +1034,11 @@ EOF
|
||||
echo i386-sequent-sysv4
|
||||
exit ;;
|
||||
i*86:UNIX_SV:4.2MP:2.*)
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# I just have to hope. -- rms.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||
exit ;;
|
||||
i*86:OS/2:*:*)
|
||||
@ -1072,7 +1070,7 @@ EOF
|
||||
fi
|
||||
exit ;;
|
||||
i*86:*:5:[678]*)
|
||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||
case `/bin/uname -X | grep "^Machine"` in
|
||||
*486*) UNAME_MACHINE=i486 ;;
|
||||
*Pentium) UNAME_MACHINE=i586 ;;
|
||||
@ -1100,10 +1098,10 @@ EOF
|
||||
exit ;;
|
||||
pc:*:*:*)
|
||||
# Left here for compatibility:
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i386.
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i386.
|
||||
echo i386-pc-msdosdjgpp
|
||||
exit ;;
|
||||
exit ;;
|
||||
Intel:Mach:3*:*)
|
||||
echo i386-pc-mach3
|
||||
exit ;;
|
||||
@ -1138,8 +1136,8 @@ EOF
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
|
||||
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@ -1173,9 +1171,9 @@ EOF
|
||||
fi
|
||||
exit ;;
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit ;;
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit ;;
|
||||
*:UNIX_System_V:4*:FTX*)
|
||||
# From Gerald Hewes <hewes@openmarket.com>.
|
||||
# How about differentiating between stratus architectures? -djm
|
||||
@ -1205,7 +1203,7 @@ EOF
|
||||
else
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
|
||||
echo powerpc-be-beos
|
||||
exit ;;
|
||||
@ -1252,8 +1250,8 @@ EOF
|
||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||
UNAME_PROCESSOR=`uname -p`
|
||||
if test "$UNAME_PROCESSOR" = "x86"; then
|
||||
UNAME_PROCESSOR=i386
|
||||
UNAME_MACHINE=pc
|
||||
UNAME_PROCESSOR=i386
|
||||
UNAME_MACHINE=pc
|
||||
fi
|
||||
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@ -1305,13 +1303,13 @@ EOF
|
||||
echo pdp10-unknown-its
|
||||
exit ;;
|
||||
SEI:*:*:SEIUX)
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:DragonFly:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit ;;
|
||||
*:*VMS:*:*)
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
case "${UNAME_MACHINE}" in
|
||||
A*) echo alpha-dec-vms ; exit ;;
|
||||
I*) echo ia64-dec-vms ; exit ;;
|
||||
@ -1486,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize
|
||||
the operating system you are using. It is advised that you
|
||||
download the most up to date version of the config scripts from
|
||||
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
and
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
|
||||
If the version you run ($0) is already up to date, please
|
||||
send the following data and any information you think might be
|
||||
|
47
contrib/ncurses/config.sub
vendored
47
contrib/ncurses/config.sub
vendored
@ -4,7 +4,7 @@
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2008-03-08'
|
||||
timestamp='2008-06-16'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@ -250,7 +250,7 @@ case $basic_machine in
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore | mep \
|
||||
| maxq | mb | microblaze | mcore | mep | metag \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
@ -306,8 +306,8 @@ case $basic_machine in
|
||||
# because (1) that's what they normally are, and
|
||||
# (2) the word "unknown" tends to confuse beginning users.
|
||||
i*86 | x86_64)
|
||||
basic_machine=$basic_machine-pc
|
||||
;;
|
||||
basic_machine=$basic_machine-pc
|
||||
;;
|
||||
# Object if more than one company name word.
|
||||
*-*-*)
|
||||
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
|
||||
@ -331,9 +331,9 @@ case $basic_machine in
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| m32c- | m32r-* | m32rle-* \
|
||||
| m32c-* | m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
@ -397,7 +397,7 @@ case $basic_machine in
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
abacus)
|
||||
abacus)
|
||||
basic_machine=abacus-unknown
|
||||
;;
|
||||
adobe68k)
|
||||
@ -463,6 +463,10 @@ case $basic_machine in
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cegcc)
|
||||
basic_machine=arm-unknown
|
||||
os=-cegcc
|
||||
;;
|
||||
convex-c1)
|
||||
basic_machine=c1-convex
|
||||
os=-bsd
|
||||
@ -530,6 +534,10 @@ case $basic_machine in
|
||||
basic_machine=m88k-motorola
|
||||
os=-sysv3
|
||||
;;
|
||||
dicos)
|
||||
basic_machine=i686-pc
|
||||
os=-dicos
|
||||
;;
|
||||
djgpp)
|
||||
basic_machine=i586-pc
|
||||
os=-msdosdjgpp
|
||||
@ -1217,8 +1225,8 @@ esac
|
||||
if [ x"$os" != x"" ]
|
||||
then
|
||||
case $os in
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# -solaris* is a basic system type, with this one exception.
|
||||
-solaris1 | -solaris1.*)
|
||||
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
||||
@ -1252,7 +1260,7 @@ case $os in
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
@ -1301,7 +1309,7 @@ case $os in
|
||||
-opened*)
|
||||
os=-openedition
|
||||
;;
|
||||
-os400*)
|
||||
-os400*)
|
||||
os=-os400
|
||||
;;
|
||||
-wince*)
|
||||
@ -1350,7 +1358,7 @@ case $os in
|
||||
-sinix*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-tpf*)
|
||||
-tpf*)
|
||||
os=-tpf
|
||||
;;
|
||||
-triton*)
|
||||
@ -1392,6 +1400,9 @@ case $os in
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
-dicos*)
|
||||
os=-dicos
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
@ -1414,10 +1425,10 @@ else
|
||||
# system, and we'll never get to this point.
|
||||
|
||||
case $basic_machine in
|
||||
score-*)
|
||||
score-*)
|
||||
os=-elf
|
||||
;;
|
||||
spu-*)
|
||||
spu-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-acorn)
|
||||
@ -1429,8 +1440,8 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
@ -1457,7 +1468,7 @@ case $basic_machine in
|
||||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mep-*)
|
||||
mep-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-cisco)
|
||||
@ -1484,7 +1495,7 @@ case $basic_machine in
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-knuth)
|
||||
*-knuth)
|
||||
os=-mmixware
|
||||
;;
|
||||
*-wec)
|
||||
|
4172
contrib/ncurses/configure
vendored
4172
contrib/ncurses/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
dnl***************************************************************************
|
||||
dnl Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. *
|
||||
dnl Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
|
||||
dnl *
|
||||
dnl Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
dnl copy of this software and associated documentation files (the *
|
||||
@ -28,14 +28,14 @@ dnl***************************************************************************
|
||||
dnl
|
||||
dnl Author: Thomas E. Dickey 1995-on
|
||||
dnl
|
||||
dnl $Id: configure.in,v 1.433 2008/04/12 23:39:06 tom Exp $
|
||||
dnl $Id: configure.in,v 1.454 2008/10/18 14:53:32 tom Exp $
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl
|
||||
dnl See http://invisible-island.net/autoconf/ for additional information.
|
||||
dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
AC_PREREQ(2.13.20020210)
|
||||
AC_REVISION($Revision: 1.433 $)
|
||||
AC_REVISION($Revision: 1.454 $)
|
||||
AC_INIT(ncurses/base/lib_initscr.c)
|
||||
AC_CONFIG_HEADER(include/ncurses_cfg.h:include/ncurses_cfg.hin)
|
||||
|
||||
@ -361,12 +361,7 @@ AC_MSG_RESULT($LD_MODEL)
|
||||
|
||||
case $DFT_LWR_MODEL in
|
||||
shared)
|
||||
AC_MSG_CHECKING(if rpath option should be used)
|
||||
AC_ARG_ENABLE(rpath,
|
||||
[ --enable-rpath use rpath option when generating shared libraries],
|
||||
[cf_cv_ld_rpath=$enableval],
|
||||
[cf_cv_ld_rpath=no])
|
||||
AC_MSG_RESULT($cf_cv_ld_rpath)
|
||||
CF_ENABLE_RPATH
|
||||
AC_MSG_CHECKING(if shared libraries should be relinked during install)
|
||||
AC_ARG_ENABLE(relink,
|
||||
[ --disable-relink relink shared libraries during install],
|
||||
@ -428,6 +423,8 @@ if test "$use_database" != no ; then
|
||||
[ --with-hashed-db specify hashed-database library],,
|
||||
[with_hashed_db=no])
|
||||
AC_MSG_RESULT($with_hashed_db)
|
||||
else
|
||||
with_hashed_db=no
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for list of fallback descriptions)
|
||||
@ -504,12 +501,13 @@ AC_MSG_RESULT($with_big_core)
|
||||
test "$with_big_core" = "yes" && AC_DEFINE(HAVE_BIG_CORE)
|
||||
|
||||
### ISO C only guarantees 512-char strings, we have tables which load faster
|
||||
### when constructed using "big" strings.
|
||||
### when constructed using "big" strings. More than the C compiler, the awk
|
||||
### program is a limit on most vendor UNIX systems. Check that we can build.
|
||||
AC_MSG_CHECKING(if big-strings option selected)
|
||||
AC_ARG_ENABLE(big-strings,
|
||||
[ --disable-big-strings assume compiler has only standard-size strings],
|
||||
[with_big_strings=no],
|
||||
[with_big_strings=yes])
|
||||
[with_big_strings=$enableval],
|
||||
[CF_AWK_BIG_PRINTF(12000,with_big_strings)])
|
||||
AC_MSG_RESULT($with_big_strings)
|
||||
|
||||
USE_BIG_STRINGS=0
|
||||
@ -681,10 +679,10 @@ if test "$with_widec" = yes ; then
|
||||
CF_PREDEFINE(_XOPEN_SOURCE_EXTENDED)
|
||||
# with_overwrite=no
|
||||
NCURSES_CH_T=cchar_t
|
||||
AC_CHECK_FUNCS(putwc btowc wctob mbtowc wctomb mblen mbrlen mbrtowc)
|
||||
AC_CHECK_FUNCS(putwc btowc wctob mbtowc wctomb mblen mbrlen mbrtowc wcsrtombs mbsrtowcs wcstombs mbstowcs)
|
||||
if test "$ac_cv_func_putwc" != yes ; then
|
||||
CF_LIBUTF8
|
||||
if test "$cf_cv_libutf8" = yes ; then
|
||||
CF_UTF8_LIB
|
||||
if test "$cf_cv_utf8_lib" != no ; then
|
||||
NCURSES_LIBUTF8=1
|
||||
fi
|
||||
fi
|
||||
@ -744,6 +742,18 @@ NCURSES_TPARM_VARARGS=0
|
||||
test "$with_tparm_varargs" = yes && NCURSES_TPARM_VARARGS=1
|
||||
AC_SUBST(NCURSES_TPARM_VARARGS)
|
||||
|
||||
### use option --disable-tic-depends to make libtic not explicitly depend on ncurses/ncursesw
|
||||
if test "$with_ticlib" != no ; then
|
||||
AC_MSG_CHECKING(if you want tic library to use explicit dependency on ncurses$LIB_SUFFIX library)
|
||||
AC_ARG_ENABLE(tic-depends,
|
||||
[ --disable-tic-depends link tic library without explicit dependency on ncurses library],
|
||||
[with_tic_depends=$enableval],
|
||||
[with_tic_depends=yes])
|
||||
AC_MSG_RESULT($with_tic_depends)
|
||||
else
|
||||
with_tic_depends=no
|
||||
fi
|
||||
|
||||
### use option --with-bool to override bool's type
|
||||
AC_MSG_CHECKING(for type of bool)
|
||||
AC_ARG_WITH(bool,
|
||||
@ -836,6 +846,40 @@ if test "$with_ext_const" = yes ; then
|
||||
fi
|
||||
AC_SUBST(NCURSES_CONST)
|
||||
|
||||
### use option --enable-ext-colors to turn on use of colors beyond 16.
|
||||
AC_MSG_CHECKING(if you want to use extended colors)
|
||||
AC_ARG_ENABLE(ext-colors,
|
||||
[ --enable-ext-colors compile for 256-color support],
|
||||
[with_ext_colors=$enableval],
|
||||
[with_ext_colors=no])
|
||||
AC_MSG_RESULT($with_ext_colors)
|
||||
NCURSES_EXT_COLORS=0
|
||||
if test "$with_ext_colors" = yes ; then
|
||||
if test "$with_widec" != yes ; then
|
||||
AC_MSG_ERROR(This option applies only to wide-character library)
|
||||
else
|
||||
# cannot be ABI 5 since it changes sizeof(cchar_t)
|
||||
CF_NCURSES_ABI_6
|
||||
fi
|
||||
NCURSES_EXT_COLORS=1
|
||||
AC_DEFINE(NCURSES_EXT_COLORS)
|
||||
fi
|
||||
AC_SUBST(NCURSES_EXT_COLORS)
|
||||
|
||||
### use option --enable-ext-mouse to modify coding to support 5-button mice
|
||||
AC_MSG_CHECKING(if you want to use extended mouse encoding)
|
||||
AC_ARG_ENABLE(ext-mouse,
|
||||
[ --enable-ext-mouse compile for extended mouse-encoding],
|
||||
[with_ext_mouse=$enableval],
|
||||
[with_ext_mouse=no])
|
||||
AC_MSG_RESULT($with_ext_mouse)
|
||||
NCURSES_MOUSE_VERSION=1
|
||||
if test "$with_ext_mouse" = yes ; then
|
||||
NCURSES_MOUSE_VERSION=2
|
||||
CF_NCURSES_ABI_6
|
||||
fi
|
||||
AC_SUBST(NCURSES_MOUSE_VERSION)
|
||||
|
||||
AC_MSG_CHECKING(if you want \$NCURSES_NO_PADDING code)
|
||||
AC_ARG_ENABLE(no-padding,
|
||||
[ --enable-no-padding compile with $NCURSES_NO_PADDING code],
|
||||
@ -935,47 +979,35 @@ AC_ARG_ENABLE(colorfgbg,
|
||||
AC_MSG_RESULT($with_colorfgbg)
|
||||
test "$with_colorfgbg" = yes && AC_DEFINE(USE_COLORFGBG)
|
||||
|
||||
### use option --enable-ext-colors to turn on use of colors beyond 16.
|
||||
AC_MSG_CHECKING(if you want to use experimental extended colors)
|
||||
AC_ARG_ENABLE(ext-colors,
|
||||
[ --enable-ext-colors compile for experimental 256-color support],
|
||||
[with_ext_colors=$enableval],
|
||||
[with_ext_colors=no])
|
||||
AC_MSG_RESULT($with_ext_colors)
|
||||
NCURSES_EXT_COLORS=0
|
||||
if test "$with_ext_colors" = yes ; then
|
||||
if test "$with_widec" != yes ; then
|
||||
AC_MSG_ERROR(This option applies only to wide-character library)
|
||||
else
|
||||
# cannot be ABI 5 since it changes sizeof(cchar_t)
|
||||
CF_NCURSES_ABI_6
|
||||
fi
|
||||
NCURSES_EXT_COLORS=1
|
||||
AC_DEFINE(NCURSES_EXT_COLORS)
|
||||
fi
|
||||
AC_SUBST(NCURSES_EXT_COLORS)
|
||||
|
||||
### use option --enable-ext-mouse to modify coding to support 5-button mice
|
||||
AC_MSG_CHECKING(if you want to use experimental extended mouse encoding)
|
||||
AC_ARG_ENABLE(ext-mouse,
|
||||
[ --enable-ext-mouse compile for experimental mouse-encoding],
|
||||
[with_ext_mouse=$enableval],
|
||||
[with_ext_mouse=no])
|
||||
AC_MSG_RESULT($with_ext_mouse)
|
||||
NCURSES_MOUSE_VERSION=1
|
||||
if test "$with_ext_mouse" = yes ; then
|
||||
NCURSES_MOUSE_VERSION=2
|
||||
CF_NCURSES_ABI_6
|
||||
fi
|
||||
AC_SUBST(NCURSES_MOUSE_VERSION)
|
||||
|
||||
# This is still experimental (20080329), but should ultimately be moved to
|
||||
# the script-block --with-normal, etc.
|
||||
CF_WITH_PTHREAD
|
||||
|
||||
AC_MSG_CHECKING(if you want to use weak-symbols for pthreads)
|
||||
AC_ARG_ENABLE(weak-symbols,
|
||||
[ --enable-weak-symbols enable weak-symbols for pthreads],
|
||||
[use_weak_symbols=$withval],
|
||||
[use_weak_symbols=no])
|
||||
AC_MSG_RESULT($use_weak_symbols)
|
||||
if test "$use_weak_symbols" = yes ; then
|
||||
CF_WEAK_SYMBOLS
|
||||
else
|
||||
cf_cv_weak_symbols=no
|
||||
fi
|
||||
|
||||
if test $cf_cv_weak_symbols = yes ; then
|
||||
AC_DEFINE(USE_WEAK_SYMBOLS)
|
||||
fi
|
||||
|
||||
PTHREAD=
|
||||
if test "$with_pthread" = "yes" ; then
|
||||
AC_DEFINE(USE_PTHREADS)
|
||||
enable_reentrant=yes
|
||||
if test $cf_cv_weak_symbols = yes ; then
|
||||
PTHREAD=-lpthread
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(PTHREAD)
|
||||
|
||||
# Reentrant code has to be opaque; there's little advantage to making ncurses
|
||||
# opaque outside of that, so there is no --enable-opaque option. We can use
|
||||
@ -992,7 +1024,11 @@ if test "$with_reentrant" = yes ; then
|
||||
cf_cv_enable_opaque="NCURSES_INTERNALS"
|
||||
NCURSES_OPAQUE=1
|
||||
NCURSES_SIZE_T=int
|
||||
LIB_SUFFIX="t${LIB_SUFFIX}"
|
||||
if test $cf_cv_weak_symbols = yes ; then
|
||||
CF_REMOVE_LIB(LIBS,$LIBS,pthread)
|
||||
else
|
||||
LIB_SUFFIX="t${LIB_SUFFIX}"
|
||||
fi
|
||||
AC_DEFINE(USE_REENTRANT)
|
||||
CF_NCURSES_ABI_6
|
||||
else
|
||||
@ -1297,6 +1333,20 @@ if test -n "$CXX" ; then
|
||||
|
||||
AC_CHECK_HEADERS(iostream typeinfo)
|
||||
|
||||
if test x"$ac_cv_header_iostream" = xyes ; then
|
||||
AC_MSG_CHECKING(if iostream uses std-namespace)
|
||||
AC_TRY_COMPILE([
|
||||
#include <iostream>
|
||||
using std::endl;
|
||||
using std::cerr;],[
|
||||
cerr << "testing" << endl;
|
||||
],[cf_iostream_namespace=yes],[cf_iostream_namespace=no])
|
||||
AC_MSG_RESULT($cf_iostream_namespace)
|
||||
if test "$cf_iostream_namespace" = yes ; then
|
||||
AC_DEFINE(IOSTREAM_NAMESPACE)
|
||||
fi
|
||||
fi
|
||||
|
||||
CF_BOOL_DECL
|
||||
CF_BOOL_SIZE
|
||||
CF_ETIP_DEFINES
|
||||
@ -1527,16 +1577,7 @@ AC_SUBST(DFT_ARG_SUFFIX)dnl the string to append to "-lncurses" ("")
|
||||
AC_MSG_RESULT($DFT_ARG_SUFFIX)
|
||||
|
||||
AC_MSG_CHECKING(default library-dependency suffix)
|
||||
CF_LIB_SUFFIX($DFT_LWR_MODEL,DFT_DEP_SUFFIX)dnl
|
||||
DFT_LIB_SUFFIX=$DFT_DEP_SUFFIX
|
||||
if test $DFT_LWR_MODEL = shared ; then
|
||||
case $cf_cv_system_name in #(vi
|
||||
cygwin*)
|
||||
DFT_DEP_SUFFIX=".dll.a"
|
||||
DFT_LIB_SUFFIX=".dll"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
CF_LIB_SUFFIX($DFT_LWR_MODEL,DFT_LIB_SUFFIX,DFT_DEP_SUFFIX)dnl
|
||||
AC_SUBST(DFT_DEP_SUFFIX)dnl the corresponding library-suffix (".a")
|
||||
AC_MSG_RESULT($DFT_DEP_SUFFIX)
|
||||
|
||||
@ -1551,7 +1592,7 @@ AC_MSG_CHECKING(c++ library-dependency suffix)
|
||||
if test "$with_libtool" != "no"; then
|
||||
CXX_LIB_SUFFIX=$DFT_DEP_SUFFIX
|
||||
else
|
||||
CF_LIB_SUFFIX(normal,CXX_LIB_SUFFIX)dnl we normally make a static library
|
||||
CF_LIB_SUFFIX(normal,CXX_LIB_SUFFIX,CXX_DEP_SUFFIX)dnl we normally make a static library
|
||||
fi
|
||||
AC_MSG_RESULT($CXX_LIB_SUFFIX)
|
||||
AC_SUBST(CXX_LIB_SUFFIX)
|
||||
@ -1627,7 +1668,11 @@ else
|
||||
TINFO_NAME=${LIB_NAME}
|
||||
TINFO_SUFFIX=${DFT_LIB_SUFFIX}
|
||||
TINFO_ARG_SUFFIX=${LIB_NAME}${DFT_ARG_SUFFIX}
|
||||
TICS_LIST="$SHLIB_LIST -l${LIB_NAME}${DFT_ARG_SUFFIX}"
|
||||
if test "$with_tic_depends" = yes ; then
|
||||
TICS_LIST="$SHLIB_LIST -l${LIB_NAME}${DFT_ARG_SUFFIX}"
|
||||
else
|
||||
TICS_LIST="$SHLIB_LIST"
|
||||
fi
|
||||
|
||||
TINFO_ARGS="-L${LIB_DIR} -l${LIB_NAME}${DFT_ARG_SUFFIX}"
|
||||
fi
|
||||
@ -1771,6 +1816,7 @@ cf_cv_prog_CC_c_o=$cf_cv_prog_CC_c_o
|
||||
cf_cv_prog_CXX_c_o=$cf_cv_prog_CXX_c_o
|
||||
cf_cv_rel_version="$cf_cv_rel_version"
|
||||
cf_cv_rm_so_locs="$cf_cv_rm_so_locs"
|
||||
cf_cv_shared_soname='$cf_cv_shared_soname'
|
||||
cf_cv_shlib_version="$cf_cv_shlib_version"
|
||||
cf_cv_shlib_version_infix="$cf_cv_shlib_version_infix"
|
||||
cf_cv_system_name="$cf_cv_system_name"
|
||||
|
@ -25,7 +25,7 @@
|
||||
# use or other dealings in this Software without prior written #
|
||||
# authorization. #
|
||||
##############################################################################
|
||||
# $Id: dist.mk,v 1.641 2008/05/03 12:31:08 tom Exp $
|
||||
# $Id: dist.mk,v 1.671 2008/11/02 00:58:38 tom Exp $
|
||||
# Makefile for creating ncurses distributions.
|
||||
#
|
||||
# This only needs to be used directly as a makefile by developers, but
|
||||
@ -36,8 +36,8 @@ SHELL = /bin/sh
|
||||
|
||||
# These define the major/minor/patch versions of ncurses.
|
||||
NCURSES_MAJOR = 5
|
||||
NCURSES_MINOR = 6
|
||||
NCURSES_PATCH = 20080503
|
||||
NCURSES_MINOR = 7
|
||||
NCURSES_PATCH = 20081102
|
||||
|
||||
# We don't append the patch to the version, since this only applies to releases
|
||||
VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
|
||||
@ -91,6 +91,11 @@ doc/hackguide.doc: doc/html/hackguide.html
|
||||
#
|
||||
# The distributed html files are formatted using
|
||||
# configure --without-manpage-renames
|
||||
#
|
||||
# The edit_man.sed script is built as a side-effect of installing the manpages.
|
||||
# If that conflicts with the --without-manpage-renames, you can install those
|
||||
# in a different location using the --with-install-prefix option of the
|
||||
# configure script.
|
||||
MANPROG = tbl | nroff -mandoc -rLL=65n -rLT=71n -Tascii
|
||||
|
||||
manhtml:
|
||||
|
@ -1,8 +1,8 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
|
||||
<!--
|
||||
$Id: announce.html,v 1.51 2006/12/17 23:32:42 tom Exp $
|
||||
$Id: announce.html,v 1.52 2008/11/02 01:05:08 tom Exp $
|
||||
****************************************************************************
|
||||
* Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. *
|
||||
* Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the *
|
||||
@ -31,13 +31,13 @@
|
||||
-->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Announcing ncurses 5.6</TITLE>
|
||||
<TITLE>Announcing ncurses 5.7</TITLE>
|
||||
<link rev=made href="mailto:bug-ncurses@gnu.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<H1>Announcing ncurses 5.6</H1>
|
||||
<H1>Announcing ncurses 5.7</H1>
|
||||
|
||||
The ncurses (new curses) library is a free software emulation of
|
||||
curses in System V Release 4.0, and more. It uses terminfo format,
|
||||
@ -69,185 +69,170 @@ the GNU distribution site
|
||||
|
||||
<H1>Release Notes</H1>
|
||||
|
||||
This release is designed to be upward compatible from ncurses 5.0 through 5.5;
|
||||
This release is designed to be upward compatible from ncurses 5.0 through 5.6;
|
||||
very few applications will require recompilation, depending on the platform.
|
||||
These are the highlights from the change-log since ncurses 5.5 release.
|
||||
These are the highlights from the change-log since ncurses 5.6 release.
|
||||
<p>
|
||||
Interface changes:
|
||||
<ul>
|
||||
<li>generate linkable stubs for some macros:
|
||||
<br>
|
||||
getbegx, getbegy, getcurx, getcury, getmaxx, getmaxy, getparx,
|
||||
getpary, getpary,
|
||||
<br>
|
||||
and (for libncursesw)
|
||||
<br>
|
||||
wgetbkgrnd
|
||||
getattrs
|
||||
|
||||
</ul>
|
||||
New features and improvements:
|
||||
<ul>
|
||||
<li>library
|
||||
<ul>
|
||||
<li>support hashed databases for the terminal descriptions.
|
||||
This uses the Berkeley database, has been tested for
|
||||
several versions on different platforms.
|
||||
<li>new flavor of the ncurses library provides rudimentary
|
||||
support for POSIX threads. Several functions are
|
||||
reentrant, but most require either a window-level or
|
||||
screen-level mutex.<br>
|
||||
(This is <em>API</em>-compatible,
|
||||
but not <em>ABI</em>-compatible with the normal library).
|
||||
|
||||
<li>add <code>use_legacy_coding()</code> function to support
|
||||
lynx's font-switching feature.
|
||||
<li>add <code>NCURSES_OPAQUE</code> symbol to curses.h, will
|
||||
use to make structs opaque in selected configurations.
|
||||
|
||||
<li>add extension <code>nofilter()</code>, to cancel a prior
|
||||
<code>filter()</code> call.
|
||||
<li>add <code>NCURSES_EXT_FUNCS</code> and
|
||||
<code>NCURSES_EXT_COLORS</code> symbols to curses.h to make
|
||||
it simpler to tell if the extended functions and/or colors
|
||||
are declared.
|
||||
|
||||
<li>add/install a package config script, e.g.,
|
||||
<code>ncurses5-config</code> or
|
||||
<code>ncursesw5-config</code>, according to
|
||||
configuration options.
|
||||
<li>add wresize() to C++ binding
|
||||
|
||||
<li>provide ifdef for <code>NCURSES_NOMACROS</code> which
|
||||
suppresses most macro definitions from curses.h, i.e.,
|
||||
where a macro is defined to override a function to improve
|
||||
performance.
|
||||
<li>eliminate fixed-buffer vsprintf() calls in C++ binding.
|
||||
|
||||
<li>make ifdef's consistent in <code>curses.h</code> for the
|
||||
extended colors so the header file can be used for the
|
||||
normal curses library. The header file installed for
|
||||
extended colors is a variation of the wide-character
|
||||
configuration.
|
||||
<li>add several functions to C++ binding which wrap C functions
|
||||
that pass a WINDOW* parameter.
|
||||
|
||||
<li>improve <code>tgetstr()</code> by making the return value
|
||||
point into the user's buffer, if provided.
|
||||
<li>adapt mouse-handling code from menu library in form-library
|
||||
|
||||
<li>add ifdef's allowing ncurses to be built with
|
||||
<code>tparm()</code> using either varargs (the existing
|
||||
status), or using a fixed-parameter list (to match X/Open).
|
||||
<li>improve tracing for form library, showing created forms,
|
||||
fields, etc.
|
||||
|
||||
<li>widen the test for xterm <code>kmous</code> a little to
|
||||
<code>allow</code> for other
|
||||
strings than "\E[M", e.g., for <code>xterm-sco</code>
|
||||
functionality in xterm.
|
||||
<li>make $NCURSES_NO_PADDING feature work for termcap interface .
|
||||
|
||||
<li>modify <code>wgetnstr()</code> to return
|
||||
<code>KEY_RESIZE</code> if a sigwinch occurs.
|
||||
<li>add check to trace-file open, if the given name is a
|
||||
directory, add ".log" to the name and try again.
|
||||
|
||||
<li>move prototypes for wide-character trace functions from
|
||||
curses.tail to curses.wide to avoid accidental reference to
|
||||
those if <code>_XOPEN_SOURCE_EXTENDED</code> is defined
|
||||
without ensuring that <wchar.h> is included.
|
||||
|
||||
<li>change the way shared libraries (other than libtool) are
|
||||
installed. Rather than copying the build-tree's libraries,
|
||||
link the shared objects into the install directory. This
|
||||
makes the <code>--with-rpath</code> option work except with
|
||||
<code>$(DESTDIR)</code>.
|
||||
|
||||
<li>several improvements for rendering in hpterm. These are
|
||||
only available if the library is configured using
|
||||
<code>--enable-xmc-glitch</code>.
|
||||
|
||||
<li>Add <code>NCURSES_NO_HARD_TABS</code> and
|
||||
<code>NCURSES_NO_MAGIC_COOKIE</code> environment variables
|
||||
to allow runtime suppression of the related hard-tabs and
|
||||
xmc-glitch features.
|
||||
<li>several new manpages: curs_legacy.3x, curs_memleaks.3x,
|
||||
curs_opaque.3x and curs_threads.3x
|
||||
</ul>
|
||||
|
||||
<li>programs:
|
||||
<ul>
|
||||
<li>add new test programs: chgat.c, demo_altkeys.c,
|
||||
echochar.c, foldkeys.c, movewindow.c, redraw.c, (noting
|
||||
that existing test programs also were modified to test
|
||||
additional features).
|
||||
<li>modified three test-programs to demonstrate the threading
|
||||
support in this version: ditto, rain, worm.
|
||||
|
||||
<li>modify tack to test extended capability function-key
|
||||
strings.
|
||||
<li>several new test-programs: demo_panels, dots_mvcur,
|
||||
inch_wide, inchs, key_name, key_names, savescreen,
|
||||
savescreen.sh test_arrays, test_get_wstr, test_getstr,
|
||||
test_instr, test_inwstr and test_opaque.
|
||||
|
||||
<li>modify toe to access termcap data, e.g., via <code>cgetent()</code>
|
||||
functions, or as a text file if those are not available.
|
||||
<li>add <code>adacurses-config</code> to the Ada95 install.
|
||||
|
||||
<li>improve infocmp/tic <code>-f</code> option formatting.
|
||||
<li>modify tic <code>-f</code> option to format spaces as
|
||||
<code>\s</code> to prevent them from being lost when that
|
||||
is read back in unformatted strings.
|
||||
|
||||
<li>add <code>toe -a</code> option, to show all databases.
|
||||
This uses new private interfaces in the ncurses library for
|
||||
iterating through the list of databases.
|
||||
|
||||
<li>modify <code>MKfallback.sh</code> to use
|
||||
<code>tic -x</code> when constructing fallback tables to
|
||||
allow extended capabilities to be retrieved from a fallback entry.
|
||||
<li>The <code>tack</code> program is now distributed separately
|
||||
from ncurses.
|
||||
</ul>
|
||||
|
||||
<li>terminal database
|
||||
<ul>
|
||||
<li>add terminfo entries for xfce terminal (xfce) and multi gnome terminal (mgt)
|
||||
<li>add nsterm-16color entry
|
||||
<li>updated mlterm terminfo entry
|
||||
<li>add kon, kon2 and jfbterm terminfo entry
|
||||
<li>remove invis capability from klone+sgr, mainly used by linux entry, since it does not really do this
|
||||
<li>add ka2, kb1, kb3, kc2 to vt220-keypad as an extension
|
||||
<li>add shifted up/down arrow codes to xterm-new as kind/kri strings
|
||||
<li>add hpterm-color terminfo entry
|
||||
<li>add 256color variants of terminfo entries for programs which are reported to implement this feature
|
||||
<li>correct order of use-clauses in rxvt-basic entry which made codes for f1-f4 vt100-style rather than vt220-style.
|
||||
<li>added entries:
|
||||
<ul>
|
||||
<li><code>Eterm-256color</code>,
|
||||
<code>Eterm-88color</code> and
|
||||
<code>rxvt-88color</code>
|
||||
<li><code>aterm</code>
|
||||
<li><code>konsole-256color</code>
|
||||
<li><code>mrxvt</code>
|
||||
<li><code>screen.mlterm</code>
|
||||
<li><code>screen.rxvt</code>
|
||||
<li><code>teraterm4.59</code> is now the primary primary
|
||||
teraterm entry, renamed original to
|
||||
<code>teraterm2.3</code>
|
||||
<li><code>9term</code> terminal
|
||||
<li>Newbury Data entries
|
||||
</ul>
|
||||
<li>updated/improved entries:
|
||||
<ul>
|
||||
<li><code>gnome</code> to version 2.22.3
|
||||
<li><code>h19</code>, <code>z100</code>
|
||||
<li><code>konsole</code> to version 1.6.6
|
||||
<li><code>mlterm</code>, <code>mlterm+pcfkeys</code>
|
||||
<li><code>xterm</code>, and building-blocks for function-keys
|
||||
to <a href="http://invisible-island.net/xterm/xterm.log.html#xterm_230">xterm patch #230</a>.
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
Major bug fixes:
|
||||
<ul>
|
||||
<li>correct a typo in configure <code>--with-bool</code> option for the
|
||||
case where <code>--without-cxx</code> is used.
|
||||
<li>add logic to tic for cancelling strings in user-defined
|
||||
capabilities
|
||||
(this is <em>needed</em> for
|
||||
current <code>konsole</code> terminfo entry).
|
||||
|
||||
<li>move assignment from environment variable <code>ESCDELAY</code>
|
||||
from <code>initscr()</code> down to <code>newterm()</code> so the
|
||||
environment variable affects timeouts for terminals opened with
|
||||
newterm() as well.
|
||||
<li>modify <code>mk-1st.awk</code> so the generated makefile rules for
|
||||
linking or installing shared libraries do not first remove the
|
||||
library, in case it is in use, e.g., <code>libncurses.so</code> by
|
||||
<code>/bin/sh</code>.
|
||||
|
||||
<li>modify <code>werase</code> to clear multicolumn characters that
|
||||
extend into a derived window.
|
||||
<li>correct check for notimeout() in wgetch().
|
||||
|
||||
<li>modify <code>wchgat()</code> to mark updated cells as changed so a
|
||||
refresh will repaint those cells.
|
||||
<li>fix a sign-extension bug in infocmp's repair_acsc() function.
|
||||
|
||||
<li>correct logic in <code>wadd_wch()</code> and
|
||||
<code>wecho_wch()</code>, which did not guard against passing the
|
||||
multi-column attribute into a call on <code>waddch()</code>, e.g.,
|
||||
using data returned by <code>win_wch()</code>
|
||||
<li>change winnstr() to stop at the end of the line.
|
||||
|
||||
<li>fix redrawing of windows other than <code>stdscr</code> using
|
||||
<code>wredrawln()</code> by touching the corresponding rows in
|
||||
<code>curscr</code>.
|
||||
<li>make Ada95 demo_panels() example work.
|
||||
|
||||
<li>reduce memory leaks in repeated calls to <code>tgetent()</code> by
|
||||
remembering the last <code>TERMINAL*</code> value allocated to hold
|
||||
the corresponding data and freeing that if the
|
||||
<code>tgetent()</code> result buffer is the same as the previous
|
||||
call.
|
||||
<li>fix for adding a non-spacing character at the beginning of a line.
|
||||
|
||||
<li>modify <code>read_termtype()</code> so the <code>term_names</code>
|
||||
data is always allocated as part of the <code>str_table</code>, a
|
||||
better fix for a memory leak.
|
||||
<li>fill in extended-color pair to make colors work
|
||||
for wide-characters using extended-colors.
|
||||
|
||||
<li>fix <code>wins_nwstr(),</code> which did not handle single-column
|
||||
non-8bit codes.
|
||||
<li>improve refresh of window on top of multi-column characters,
|
||||
taking into account split characters on left/right window
|
||||
boundaries.
|
||||
|
||||
<li>modify <code>wbkgrnd()</code> to avoid clearing the
|
||||
<code>A_CHARTEXT</code> attribute bits since those record the state
|
||||
of multicolumn characters.
|
||||
<li>modify <code>win_wchnstr()</code> to ensure that only a base cell
|
||||
is returned for each multi-column character.
|
||||
|
||||
<li>improve <code>SIGWINCH</code> handling by postponing its effect
|
||||
during <code>newterm()</code>, etc., when allocating screens.
|
||||
<li>improve <code>waddch()</code> and <code>winsch()</code> handling of
|
||||
EILSEQ from <code>mbrtowc()</code> by using <code>unctrl()</code>
|
||||
to display illegal bytes rather than trying to append further bytes
|
||||
to make up a valid sequence.
|
||||
|
||||
<li>remove 970913 feature for copying subwindows as they are moved in
|
||||
<code>mvwin()</code>.
|
||||
<li>restore <code>curs_set()</code> state after
|
||||
<code>endwin()</code>/<code>refresh()</code>
|
||||
|
||||
<li>add checks in <code>waddchnstr()</code> and
|
||||
<code>wadd_wchnstr()</code> to stop copying when a null character
|
||||
is found.
|
||||
<li>modify <code>keyname()</code> to use "^X" form only if
|
||||
<code>meta()</code> has been called, or if <code>keyname()</code>
|
||||
is called without initializing curses, e.g., via
|
||||
<code>initscr()</code> or <code>newterm()</code>.
|
||||
|
||||
<li>add some checks to ensure current position is within scrolling
|
||||
region before scrolling on a new line.
|
||||
<li>modify <code>unctrl()</code> to check codes in 128-255 range versus
|
||||
<code>isprint()</code>.
|
||||
If they are not printable, and locale was set, use a "M-" or "~"
|
||||
sequence.
|
||||
|
||||
<li>add a workaround to ACS mapping to allow applications such as
|
||||
test/blue.c to use the "PC ROM" characters by masking them with
|
||||
A_ALTCHARSET. This worked up til 5.5, but was lost in the revision
|
||||
of legacy coding.
|
||||
<li>improve <code>resizeterm()</code> by moving ripped-off lines, and
|
||||
repainting the soft-keys.
|
||||
|
||||
<li>modify form library to accept control characters such as newline
|
||||
in set_field_buffer(), which is compatible with Solaris.
|
||||
|
||||
<li>use <code>NCURSES_MOUSE_MASK()</code> in definition of
|
||||
<code>BUTTON_RELEASE()</code>, etc., to make those work properly
|
||||
with the <code>--enable-ext-mouse</code> configuration
|
||||
|
||||
<li>correct some functions in Ada95 binding which were using return
|
||||
value from C where none was returned.
|
||||
|
||||
<li>reviewed/fixed issues reported by Coverity and Klocwork tools.
|
||||
</ul>
|
||||
|
||||
Portability:
|
||||
@ -257,110 +242,115 @@ Portability:
|
||||
<li>new options:
|
||||
<dl>
|
||||
|
||||
<dt>--with-hashed-db
|
||||
<dd>Use Berkeley hashed database for storing terminfo data rather than storing
|
||||
each compiled entry in a separate binary file within a directory
|
||||
tree.
|
||||
<dt>--disable-big-strings
|
||||
<dd>control whether static string tables are generated as single
|
||||
large strings (to improve startup performance), or as array
|
||||
of individual strings.
|
||||
|
||||
<dt>--without-dlsym
|
||||
<dd>Do not use <code>dlsym()</code> to load GPM dynamically.
|
||||
<dt>--disable-relink
|
||||
<dd>control whether shared libraries are relinked (during install)
|
||||
when rpath is enabled.
|
||||
|
||||
<dt>--with-valgrind
|
||||
<dd>Simplify building for testing with valgrind.
|
||||
<dt>--disable-tic-depends
|
||||
<dd>make explicit whether tic library depends on ncurses/ncursesw
|
||||
library.
|
||||
|
||||
<dt>--enable-wgetch-events
|
||||
<dd>Compile with experimental wgetch-events code.
|
||||
<dt>--enable-mixed-case
|
||||
<dd>override the configure script's check if the filesystem
|
||||
supports mixed-case filenames.
|
||||
This allows one to control how the terminal database
|
||||
maps to the filesystem.
|
||||
For filesystems that do not support mixed-case, the library
|
||||
uses generate 2-character (hexadecimal) codes for the
|
||||
lower-level of the filesystem terminfo database
|
||||
|
||||
<dt>--enable-signed-char
|
||||
<dd>Store booleans in "signed char" rather than "char".
|
||||
<dt>--enable-reentrant
|
||||
<dd>builds a different flavor of the ncurses library (ncursest)
|
||||
which improves reentrant use of the
|
||||
library by reducing global and static variables
|
||||
(see the "--with-pthread" option for the threaded support).
|
||||
|
||||
<dt>--enable-weak-symbols
|
||||
<dd>use weak-symbols for linking to the POSIX thread library,
|
||||
and use the same soname for the ncurses shared library
|
||||
as the normal library (caveat: the ABI is for the threaded
|
||||
library, which makes global data accessed via functions).
|
||||
|
||||
<dt>--with-pthread
|
||||
<dd>build with the POSIX thread library (tested with AIX,
|
||||
Linux, FreeBSD, OpenBSD, HPUX, IRIX64, Solaris, Tru64).
|
||||
|
||||
<dt>--with-ticlib
|
||||
<dd>build/install the tic-support functions in a separate library
|
||||
|
||||
</dl>
|
||||
|
||||
<li>improved options:
|
||||
<dl>
|
||||
|
||||
<dt>--disable-largefile
|
||||
<dd>make the option work both ways.
|
||||
<dt>--enable-ext-colors
|
||||
<dd>requires the wide-character configuration.
|
||||
|
||||
<dt>--with-gpm
|
||||
<dd>The option now accepts a parameter,
|
||||
i.e., the name of the dynamic GPM library to load via
|
||||
<code>dlopen()</code>
|
||||
<dt>--with-chtype
|
||||
<dd>ignore option value "unsigned" is always added to
|
||||
the type in curses.h; do the same for --with-mmask-t.
|
||||
|
||||
<dt>--disable-symlinks
|
||||
<dd>The option now allows one to
|
||||
disable <code>symlink()</code> in <code>tic</code> even when
|
||||
<code>link()</code> does not work.
|
||||
<dt>--with-dmalloc
|
||||
<dd>build-fix for redefinition of <code>strndup</code>.
|
||||
|
||||
<dt>--with-hashed-db
|
||||
<dd>accepts a parameter which is the install-prefix of a given
|
||||
Berkeley Database.
|
||||
|
||||
<dt>--with-hashed-db
|
||||
<dd>the $LIBS environment variable overrides the search for the db
|
||||
library.
|
||||
|
||||
<dt>--without-hashed-db
|
||||
<dd>assumed when "--disable-database" is used.
|
||||
|
||||
</dl>
|
||||
|
||||
</ul>
|
||||
|
||||
<li>other configure/build issues: <ul> <li>remove special case for
|
||||
Darwin in <code>CF_XOPEN_SOURCE</code> configure macro.
|
||||
|
||||
<li>add configure check to ensure that <code>SIGWINCH</code> is
|
||||
defined on platforms such as OS X which exclude that when
|
||||
<code>_XOPEN_SOURCE,</code> etc., are defined
|
||||
|
||||
<li>use ld's <code>-search_paths_first</code> option on Darwin
|
||||
to work around odd search rules on that platform.
|
||||
|
||||
<li>improve ifdef's for <code>_POSIX_VDISABLE</code> in tset to
|
||||
work with Mac OS X.
|
||||
|
||||
<li>modify configure script to ensure that if the C compiler is
|
||||
used rather than the loader in making shared libraries, the
|
||||
<code>$(CFLAGS)</code> variable is also used.
|
||||
|
||||
<li>use <code>${CC}</code> rather than <code>${LD}</code> in
|
||||
shared library rules for IRIX64, Solaris to help ensure
|
||||
that initialization sections are provided for extra linkage
|
||||
requirements, e.g., of C++ applications.
|
||||
|
||||
<li>improve some shared-library configure scripting for Linux,
|
||||
FreeBSD and NetBSD to make
|
||||
<code>--with-shlib-version</code> work.
|
||||
|
||||
<li>split up dependency of <code>names.c</code> and
|
||||
<code>codes.c</code> in <code>ncurses/Makefile</code> to
|
||||
work with parallel make.
|
||||
|
||||
<li>modify <code>MKlib_gen.sh</code> to change
|
||||
preprocessor-expanded <code>_Bool</code> back to <code>bool</code>.
|
||||
|
||||
<li>modify <code>progs/Makefile.in</code> to make
|
||||
<code>tput init</code> work properly with cygwin,
|
||||
i.e., do not pass a <code>.exe</code> in the reference
|
||||
string used in check_aliases.
|
||||
<li>other configure/build issues:
|
||||
<ul>
|
||||
<li>build-fixes for LynxOS
|
||||
<li>modify shared-library rules to allow FreeBSD 3.x to use rpath.
|
||||
<li>build-fix for FreeBSD "contemporary" TTY interface.
|
||||
<li>build-fixes for AIX with libtool.
|
||||
<li>build-fixes for Darwin and libtool.
|
||||
<li>modify BeOS-specific ifdef's to build on Haiku.
|
||||
<li>corrected gcc options for building shared libraries on Solaris
|
||||
and IRIX64.
|
||||
<li>change shared-library configuration for OpenBSD, make rpath work.
|
||||
<li>build-fixes for using libutf8, e.g., on OpenBSD 3.7
|
||||
<li>add "-e" option in ncurses/Makefile.in when generating source-files
|
||||
to force earlier exit if the build environment fails unexpectedly.
|
||||
<li>add support for shared libraries for QNX.
|
||||
<li>change delimiter in <code>MKlib_gen.sh</code> from '%' to '@', to
|
||||
avoid substitution by IBM xlc to '#' as part of its extensions to
|
||||
digraphs.
|
||||
</ul>
|
||||
|
||||
<li>library:
|
||||
<ul>
|
||||
<li>ignore wide-acs line-drawing characters that
|
||||
<code>wcwidth()</code> claims are not one-column. This is
|
||||
a workaround for Solaris' broken locale support.
|
||||
|
||||
<li>reduce name-pollution in <code>term.h</code> by removing
|
||||
<code>#define</code>'s for HAVE_xxx symbols.
|
||||
|
||||
<li>fix <code>#ifdef</code> in <code>c++/internal.h</code> for
|
||||
QNX 6.1
|
||||
<li>rewrite wrapper for <code>wcrtomb()</code>, making it work on
|
||||
Solaris. This is used in the form library to determine the length
|
||||
of the buffer needed by <code>field_buffer</code>.
|
||||
<li>add/use configure script macro CF_SIG_ATOMIC_T, use the corresponding
|
||||
type for data manipulated by signal handlers.
|
||||
<li>set locale in misc/ncurses-config.in since it uses a range
|
||||
<li>disable GPM mouse support when $TERM does not happen to contain
|
||||
"linux", since Gpm_Open() no longer limits its assertion to terminals
|
||||
that it might handle, e.g., within "screen" in xterm.
|
||||
<li>reset mouse file-descriptor when unloading GPM library.
|
||||
</ul>
|
||||
|
||||
<li>test programs: <ul> <li>modify <code>test/configure</code> script
|
||||
to allow building test programs with PDCurses/X11.
|
||||
|
||||
<li>modified test programs to allow some to work with NetBSD
|
||||
curses. Several do not because NetBSD curses implements a
|
||||
subset of X/Open curses, and also lacks much of SVr4
|
||||
additions. But it is enough for comparison.
|
||||
|
||||
<li>improved <code>test/configure</code> to build test/ncurses
|
||||
on HPUX 11 using the vendor curses.
|
||||
|
||||
<li>change configure script to produce
|
||||
<code>test/Makefile</code> from data file.
|
||||
<li>test programs:
|
||||
<ul>
|
||||
<li>update test programs to build/work with various UNIX curses for
|
||||
comparisons.
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
@ -410,6 +400,8 @@ and <CODE>define_key()</CODE> allow
|
||||
you to better control the use of function keys,
|
||||
e.g., disabling the ncurses KEY_MOUSE,
|
||||
or by defining more than one control sequence to map to a given key code.
|
||||
<LI>Support for 256-color terminals, such as modern xterm, when configured
|
||||
using the <code>--enable-ext-colors</code> option.
|
||||
<LI>Support for 16-color terminals, such as aixterm and modern xterm.
|
||||
<LI>Better cursor-movement optimization. The package now features a
|
||||
cursor-local-movement computation more efficient than either BSD's
|
||||
@ -513,14 +505,10 @@ for similar applications on GNU/Linux.
|
||||
<br>
|
||||
<DT> pinfo
|
||||
<DD> Lynx-like info browser.
|
||||
<A HREF="http://dione.ids.pl/~pborys/software/pinfo/">http://dione.ids.pl/~pborys/software/pinfo/</A>
|
||||
<A HREF="https://alioth.debian.org/projects/pinfo/">https://alioth.debian.org/projects/pinfo/</A>
|
||||
<DT> tin
|
||||
<DD> newsreader, supporting color, MIME
|
||||
<A HREF="http://www.tin.org/">http://www.tin.org/</A>
|
||||
<DT> vh-1.6
|
||||
<DD> Volks-Hypertext browser for the Jargon File
|
||||
<br>
|
||||
<A HREF="http://www.debian.org/Packages/unstable/text/vh.html">http://www.debian.org/Packages/unstable/text/vh.html</A>
|
||||
</DL>
|
||||
as well as some that use ncurses for the terminfo support alone:
|
||||
<DL>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. *
|
||||
* Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the *
|
||||
@ -30,7 +30,7 @@
|
||||
* Author: Juergen Pfeifer, 1995,1997 *
|
||||
****************************************************************************/
|
||||
|
||||
/* $Id: form.priv.h,v 0.26 2006/12/17 19:47:09 tom Exp $ */
|
||||
/* $Id: form.priv.h,v 0.27 2008/09/08 20:29:05 tom Exp $ */
|
||||
|
||||
#ifndef FORM_PRIV_H
|
||||
#define FORM_PRIV_H 1
|
||||
@ -39,8 +39,6 @@
|
||||
#include "mf_common.h"
|
||||
|
||||
#if USE_WIDEC_SUPPORT
|
||||
#include <wchar.h>
|
||||
|
||||
#if HAVE_WCTYPE_H
|
||||
#include <wctype.h>
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. *
|
||||
* Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the *
|
||||
@ -32,7 +32,7 @@
|
||||
|
||||
#include "form.priv.h"
|
||||
|
||||
MODULE_ID("$Id: frm_def.c,v 1.22 2007/10/13 19:31:17 tom Exp $")
|
||||
MODULE_ID("$Id: frm_def.c,v 1.23 2008/08/04 00:07:55 tom Exp $")
|
||||
|
||||
/* this can't be readonly */
|
||||
static FORM default_form =
|
||||
@ -234,8 +234,16 @@ Connect_Fields(FORM *form, FIELD **fields)
|
||||
fields[j]->page = page_nr;
|
||||
fld = Insert_Field_By_Position(fields[j], fld);
|
||||
}
|
||||
form->page[page_nr].smin = fld->index;
|
||||
form->page[page_nr].smax = fld->sprev->index;
|
||||
if (fld)
|
||||
{
|
||||
form->page[page_nr].smin = fld->index;
|
||||
form->page[page_nr].smax = fld->sprev->index;
|
||||
}
|
||||
else
|
||||
{
|
||||
form->page[page_nr].smin = 0;
|
||||
form->page[page_nr].smax = 0;
|
||||
}
|
||||
}
|
||||
RETURN(E_OK);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#include "form.priv.h"
|
||||
|
||||
MODULE_ID("$Id: frm_driver.c,v 1.86 2008/01/19 20:11:03 tom Exp $")
|
||||
MODULE_ID("$Id: frm_driver.c,v 1.88 2008/10/18 16:25:00 tom Exp $")
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
This is the core module of the form library. It contains the majority
|
||||
@ -4176,7 +4176,7 @@ form_driver(FORM *form, int c)
|
||||
NULL /* Choice Request is generic */
|
||||
};
|
||||
size_t nMethods = (sizeof(Generic_Methods) / sizeof(Generic_Methods[0]));
|
||||
size_t method = ((BI->keycode & ID_Mask) >> ID_Shft) & 0xffff;
|
||||
size_t method = (BI->keycode >> ID_Shft) & 0xffff; /* see ID_Mask */
|
||||
|
||||
if ((method >= nMethods) || !(BI->cmd))
|
||||
res = E_SYSTEM_ERROR;
|
||||
@ -4333,15 +4333,6 @@ set_field_buffer(FIELD *field, int buffer, const char *value)
|
||||
|
||||
len = Buffer_Length(field);
|
||||
|
||||
if (buffer == 0)
|
||||
{
|
||||
for (i = 0; (value[i] != '\0') && (i < len); ++i)
|
||||
{
|
||||
if (iscntrl(UChar(value[i])))
|
||||
RETURN(E_BAD_ARGUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (Growable(field))
|
||||
{
|
||||
/* for a growable field we must assume zero terminated strings, because
|
||||
@ -4356,14 +4347,6 @@ set_field_buffer(FIELD *field, int buffer, const char *value)
|
||||
* field->cols))))
|
||||
RETURN(E_SYSTEM_ERROR);
|
||||
|
||||
/* in this case we also have to check, whether or not the remaining
|
||||
characters in value are also printable for buffer 0. */
|
||||
if (buffer == 0)
|
||||
{
|
||||
for (i = len; i < vlen; i++)
|
||||
if (iscntrl(UChar(value[i])))
|
||||
RETURN(E_BAD_ARGUMENT);
|
||||
}
|
||||
len = vlen;
|
||||
}
|
||||
}
|
||||
@ -4376,6 +4359,13 @@ set_field_buffer(FIELD *field, int buffer, const char *value)
|
||||
* There should be a better way, but this handles nonspacing characters
|
||||
* and other special cases that we really do not want to handle here.
|
||||
*/
|
||||
#if NCURSES_EXT_FUNCS
|
||||
if (wresize(field->working, field->drows, field->dcols) == ERR)
|
||||
#endif
|
||||
{
|
||||
delwin(field->working);
|
||||
field->working = newpad(field->drows, field->dcols);
|
||||
}
|
||||
wclear(field->working);
|
||||
mvwaddstr(field->working, 0, 0, value);
|
||||
|
||||
@ -4385,7 +4375,12 @@ set_field_buffer(FIELD *field, int buffer, const char *value)
|
||||
}
|
||||
else
|
||||
{
|
||||
mvwin_wchnstr(field->working, 0, 0, widevalue, (int)len);
|
||||
for (i = 0; i < (unsigned)field->drows; ++i)
|
||||
{
|
||||
mvwin_wchnstr(field->working, i, 0,
|
||||
widevalue + (i * field->dcols),
|
||||
field->dcols);
|
||||
}
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
if (CharEq(myZEROS, widevalue[i]))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. *
|
||||
* Copyright (c) 1998-2005,2008 Free Software Foundation, Inc. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the *
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
#include "form.priv.h"
|
||||
|
||||
MODULE_ID("$Id: frm_req_name.c,v 1.15 2005/04/16 16:59:27 tom Exp $")
|
||||
MODULE_ID("$Id: frm_req_name.c,v 1.16 2008/07/05 23:22:08 tom Exp $")
|
||||
|
||||
static const char *request_names[MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1] =
|
||||
{
|
||||
@ -154,7 +154,7 @@ form_request_by_name(const char *str)
|
||||
strncpy(buf, str, sizeof(buf));
|
||||
while ((i < sizeof(buf)) && (buf[i] != '\0'))
|
||||
{
|
||||
buf[i] = toupper(buf[i]);
|
||||
buf[i] = toupper(UChar(buf[i]));
|
||||
i++;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user