aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew D Fleming <mdf@FreeBSD.org>2010-09-10 16:42:16 +0000
committerMatthew D Fleming <mdf@FreeBSD.org>2010-09-10 16:42:16 +0000
commit4d369413e19e5195fe4babcb74980c4cff21df03 (patch)
treee9bea66185b980482df09793bce47717d6df59f2
parent6a4e245b76e19c5a09b70face2ea9f9e34347469 (diff)
downloadsrc-4d369413e19e5195fe4babcb74980c4cff21df03.tar.gz
src-4d369413e19e5195fe4babcb74980c4cff21df03.zip
Replace sbuf_overflowed() with sbuf_error(), which returns any error
code associated with overflow or with the drain function. While this function is not expected to be used often, it produces more information in the form of an errno that sbuf_overflowed() did.
Notes
Notes: svn path=/head/; revision=212425
-rw-r--r--share/man/man9/Makefile2
-rw-r--r--share/man/man9/sbuf.919
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c10
-rw-r--r--sys/compat/linux/linux_ioctl.c4
-rw-r--r--sys/kern/kern_sig.c2
-rw-r--r--sys/kern/subr_sbuf.c53
-rw-r--r--sys/net/if.c4
-rw-r--r--sys/security/audit/audit_bsm_klib.c2
-rw-r--r--sys/sys/sbuf.h3
9 files changed, 51 insertions, 48 deletions
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 6abafe19e09f..194eba471376 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1025,10 +1025,10 @@ MLINKS+=sbuf.9 sbuf_bcat.9 \
sbuf.9 sbuf_data.9 \
sbuf.9 sbuf_delete.9 \
sbuf.9 sbuf_done.9 \
+ sbuf.9 sbuf_error.9 \
sbuf.9 sbuf_finish.9 \
sbuf.9 sbuf_len.9 \
sbuf.9 sbuf_new.9 \
- sbuf.9 sbuf_overflowed.9 \
sbuf.9 sbuf_printf.9 \
sbuf.9 sbuf_putc.9 \
sbuf.9 sbuf_set_drain.9 \
diff --git a/share/man/man9/sbuf.9 b/share/man/man9/sbuf.9
index 7389064544fa..0b6aa908d079 100644
--- a/share/man/man9/sbuf.9
+++ b/share/man/man9/sbuf.9
@@ -45,7 +45,7 @@
.Nm sbuf_putc ,
.Nm sbuf_set_drain ,
.Nm sbuf_trim ,
-.Nm sbuf_overflowed ,
+.Nm sbuf_error ,
.Nm sbuf_finish ,
.Nm sbuf_data ,
.Nm sbuf_len ,
@@ -88,7 +88,7 @@
.Ft int
.Fn sbuf_trim "struct sbuf *s"
.Ft int
-.Fn sbuf_overflowed "struct sbuf *s"
+.Fn sbuf_error "struct sbuf *s"
.Ft int
.Fn sbuf_finish "struct sbuf *s"
.Ft char *
@@ -332,10 +332,15 @@ function removes trailing whitespace from the
.Fa sbuf .
.Pp
The
-.Fn sbuf_overflowed
-function returns a non-zero value if the
+.Fn sbuf_error
+function returns any error value that the
+.Fa sbuf
+may have accumulated, either from the drain function, or ENOMEM if the
.Fa sbuf
overflowed.
+This function is generally not needed and instead the error code from
+.Fn sbuf_finish
+is the preferred way to discover whether an sbuf had an error.
.Pp
The
.Fn sbuf_finish
@@ -437,9 +442,9 @@ functions
all return \-1 if the buffer overflowed, and zero otherwise.
.Pp
The
-.Fn sbuf_overflowed
-function
-returns a non-zero value if the buffer overflowed, and zero otherwise.
+.Fn sbuf_error
+function returns a non-zero value if the buffer has an overflow or
+drain error, and zero otherwise.
.Pp
The
.Fn sbuf_data
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c
index 63ae13ac856a..cf2f90db69d0 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c
@@ -101,6 +101,7 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio,
char buf[1024];
struct sbuf sb;
struct timespec ts;
+ int error;
/*
* If we are doing a spa_tryimport(), ignore errors.
@@ -315,9 +316,9 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio,
}
mutex_exit(&spa->spa_errlist_lock);
- sbuf_finish(&sb);
+ error = sbuf_finish(&sb);
devctl_notify("ZFS", spa->spa_name, subclass, sbuf_data(&sb));
- if (sbuf_overflowed(&sb))
+ if (error != 0)
printf("ZFS WARNING: sbuf overflowed\n");
sbuf_delete(&sb);
#endif
@@ -331,6 +332,7 @@ zfs_post_common(spa_t *spa, vdev_t *vd, const char *name)
char class[64];
struct sbuf sb;
struct timespec ts;
+ int error;
nanotime(&ts);
@@ -346,10 +348,10 @@ zfs_post_common(spa_t *spa, vdev_t *vd, const char *name)
if (vd)
sbuf_printf(&sb, " %s=%ju", FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID,
vd->vdev_guid);
- sbuf_finish(&sb);
+ error = sbuf_finish(&sb);
ZFS_LOG(1, "%s", sbuf_data(&sb));
devctl_notify("ZFS", spa->spa_name, class, sbuf_data(&sb));
- if (sbuf_overflowed(&sb))
+ if (error != 0)
printf("ZFS WARNING: sbuf overflowed\n");
sbuf_delete(&sb);
#endif
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index b6de86a3c012..07a281e2926e 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -2220,7 +2220,7 @@ again:
addrs++;
}
- if (!sbuf_overflowed(sb))
+ if (sbuf_error(sb) == 0)
valid_len = sbuf_len(sb);
}
if (addrs == 0) {
@@ -2228,7 +2228,7 @@ again:
sbuf_bcat(sb, &ifr, sizeof(ifr));
max_len += sizeof(ifr);
- if (!sbuf_overflowed(sb))
+ if (sbuf_error(sb) == 0)
valid_len = sbuf_len(sb);
}
}
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index f54d59e59f2b..d315ff1a4016 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -3093,7 +3093,7 @@ expand_name(const char *name, uid_t uid, pid_t pid, struct thread *td,
sbuf_printf(&sb, GZ_SUFFIX);
}
#endif
- if (sbuf_overflowed(&sb)) {
+ if (sbuf_error(&sb) != 0) {
log(LOG_ERR, "pid %ld (%s), uid (%lu): corename is too "
"long\n", (long)pid, name, (u_long)uid);
nomem:
diff --git a/sys/kern/subr_sbuf.c b/sys/kern/subr_sbuf.c
index 58964fb1d85e..4535337486ba 100644
--- a/sys/kern/subr_sbuf.c
+++ b/sys/kern/subr_sbuf.c
@@ -66,7 +66,6 @@ static MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
#define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC)
#define SBUF_ISDYNSTRUCT(s) ((s)->s_flags & SBUF_DYNSTRUCT)
#define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED)
-#define SBUF_HASOVERFLOWED(s) ((s)->s_flags & SBUF_OVERFLOWED)
#define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1)
#define SBUF_FREESPACE(s) ((s)->s_size - (s)->s_len - 1)
#define SBUF_CANEXTEND(s) ((s)->s_flags & SBUF_AUTOEXTEND)
@@ -247,7 +246,6 @@ sbuf_clear(struct sbuf *s)
/* don't care if it's finished or not */
SBUF_CLEARFLAG(s, SBUF_FINISHED);
- SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
s->s_error = 0;
s->s_len = 0;
}
@@ -299,10 +297,10 @@ sbuf_drain(struct sbuf *s)
int len;
KASSERT(s->s_len > 0, ("Shouldn't drain empty sbuf %p", s));
+ KASSERT(s->s_error == 0, ("Called %s with error on %p", __func__, s));
len = s->s_drain_func(s->s_drain_arg, s->s_buf, s->s_len);
if (len < 0) {
s->s_error = -len;
- SBUF_SETFLAG(s, SBUF_OVERFLOWED);
return (s->s_error);
}
KASSERT(len > 0 && len <= s->s_len,
@@ -334,7 +332,7 @@ sbuf_put_byte(int c, struct sbuf *s)
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return;
if (SBUF_FREESPACE(s) <= 0) {
/*
@@ -344,8 +342,8 @@ sbuf_put_byte(int c, struct sbuf *s)
if (s->s_drain_func != NULL)
(void)sbuf_drain(s);
else if (sbuf_extend(s, 1) < 0)
- SBUF_SETFLAG(s, SBUF_OVERFLOWED);
- if (SBUF_HASOVERFLOWED(s))
+ s->s_error = ENOMEM;
+ if (s->s_error != 0)
return;
}
s->s_buf[s->s_len++] = c;
@@ -375,11 +373,11 @@ sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
for (; str < end; str++) {
sbuf_put_byte(*str, s);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
}
return (0);
@@ -398,7 +396,7 @@ sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len)
KASSERT(s->s_drain_func == NULL,
("Nonsensical copyin to sbuf %p with a drain", s));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
if (len == 0)
return (0);
@@ -439,12 +437,12 @@ sbuf_cat(struct sbuf *s, const char *str)
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
while (*str != '\0') {
sbuf_put_byte(*str, s);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
}
return (0);
@@ -464,7 +462,7 @@ sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)
KASSERT(s->s_drain_func == NULL,
("Nonsensical copyin to sbuf %p with a drain", s));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
if (len == 0)
@@ -476,7 +474,7 @@ sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)
}
switch (copyinstr(uaddr, s->s_buf + s->s_len, len + 1, &done)) {
case ENAMETOOLONG:
- SBUF_SETFLAG(s, SBUF_OVERFLOWED);
+ s->s_error = ENOMEM;
/* fall through */
case 0:
s->s_len += done - 1;
@@ -518,7 +516,7 @@ sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
("%s called with a NULL format string", __func__));
(void)kvprintf(fmt, sbuf_putc_func, s, 10, ap);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
return (0);
}
@@ -535,7 +533,7 @@ sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
KASSERT(fmt != NULL,
("%s called with a NULL format string", __func__));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
/*
@@ -578,12 +576,12 @@ sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
len = SBUF_FREESPACE(s);
s->s_len += len;
if (!SBUF_HASROOM(s) && !SBUF_CANEXTEND(s))
- SBUF_SETFLAG(s, SBUF_OVERFLOWED);
+ s->s_error = ENOMEM;
KASSERT(s->s_len < s->s_size,
("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
return (0);
}
@@ -612,7 +610,7 @@ sbuf_putc(struct sbuf *s, int c)
{
sbuf_putc_func(c, s);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
return (0);
}
@@ -629,7 +627,7 @@ sbuf_trim(struct sbuf *s)
KASSERT(s->s_drain_func == NULL,
("%s makes no sense on sbuf %p with drain", __func__, s));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
while (s->s_len > 0 && isspace(s->s_buf[s->s_len-1]))
@@ -639,13 +637,13 @@ sbuf_trim(struct sbuf *s)
}
/*
- * Check if an sbuf overflowed
+ * Check if an sbuf has an error.
*/
int
-sbuf_overflowed(struct sbuf *s)
+sbuf_error(struct sbuf *s)
{
- return (SBUF_HASOVERFLOWED(s));
+ return (s->s_error);
}
/*
@@ -654,19 +652,18 @@ sbuf_overflowed(struct sbuf *s)
int
sbuf_finish(struct sbuf *s)
{
- int error = 0;
+ int error;
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
+ error = s->s_error;
if (s->s_drain_func != NULL) {
- error = s->s_error;
while (s->s_len > 0 && error == 0)
error = sbuf_drain(s);
- } else if (SBUF_HASOVERFLOWED(s))
- error = ENOMEM;
+ }
s->s_buf[s->s_len] = '\0';
- SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
+ s->s_error = 0;
SBUF_SETFLAG(s, SBUF_FINISHED);
#ifdef _KERNEL
return (error);
@@ -703,7 +700,7 @@ sbuf_len(struct sbuf *s)
KASSERT(s->s_drain_func == NULL,
("%s makes no sense on sbuf %p with drain", __func__, s));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
return (s->s_len);
}
diff --git a/sys/net/if.c b/sys/net/if.c
index c387dbf498fe..bd54acf28c22 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -2726,7 +2726,7 @@ again:
max_len += sa->sa_len;
}
- if (!sbuf_overflowed(sb))
+ if (sbuf_error(sb) == 0)
valid_len = sbuf_len(sb);
}
IF_ADDR_UNLOCK(ifp);
@@ -2735,7 +2735,7 @@ again:
sbuf_bcat(sb, &ifr, sizeof(ifr));
max_len += sizeof(ifr);
- if (!sbuf_overflowed(sb))
+ if (sbuf_error(sb) == 0)
valid_len = sbuf_len(sb);
}
}
diff --git a/sys/security/audit/audit_bsm_klib.c b/sys/security/audit/audit_bsm_klib.c
index c8d40356cfe8..f26f86cabc94 100644
--- a/sys/security/audit/audit_bsm_klib.c
+++ b/sys/security/audit/audit_bsm_klib.c
@@ -548,7 +548,7 @@ audit_canon_path(struct thread *td, char *path, char *cpath)
* the supplied buffer being overflowed. Check to see if this is the
* case.
*/
- if (sbuf_overflowed(&sbf) != 0) {
+ if (sbuf_error(&sbf) != 0) {
cpath[0] = '\0';
return;
}
diff --git a/sys/sys/sbuf.h b/sys/sys/sbuf.h
index be3d80c52406..eeb38140da52 100644
--- a/sys/sys/sbuf.h
+++ b/sys/sys/sbuf.h
@@ -51,7 +51,6 @@ struct sbuf {
#define SBUF_USRFLAGMSK 0x0000ffff /* mask of flags the user may specify */
#define SBUF_DYNAMIC 0x00010000 /* s_buf must be freed */
#define SBUF_FINISHED 0x00020000 /* set by sbuf_finish() */
-#define SBUF_OVERFLOWED 0x00040000 /* sbuf overflowed */
#define SBUF_DYNSTRUCT 0x00080000 /* sbuf must be freed */
int s_flags; /* flags */
};
@@ -76,7 +75,7 @@ int sbuf_vprintf(struct sbuf *, const char *, __va_list)
int sbuf_putc(struct sbuf *, int);
void sbuf_set_drain(struct sbuf *, sbuf_drain_func *, void *);
int sbuf_trim(struct sbuf *);
-int sbuf_overflowed(struct sbuf *);
+int sbuf_error(struct sbuf *);
int sbuf_finish(struct sbuf *);
char *sbuf_data(struct sbuf *);
int sbuf_len(struct sbuf *);