Re: nfsrv_mknod(): missing vput() in error path

2016-07-03 Thread Bob Beck
Makes sense to me martin


On Sun, Jul 3, 2016 at 1:16 PM, Martin Natano  wrote:
> When perfoming a mknod operation over NFS it can happen that another
> client creates a file with the same name between the namei() and
> VOP_MKNOD() calls in domknod(). This leads to an error path in
> nfsrv_mknod() being triggered. In that error path there is a
> vput(nd.ni_np) missing, resulting in the vnode getting stuck with a
> stale reference and lock, while it shouldn't have either.
>
> Ok?
>
> natano
>
>
> Index: nfs/nfs_serv.c
> ===
> RCS file: /cvs/src/sys/nfs/nfs_serv.c,v
> retrieving revision 1.108
> diff -u -p -r1.108 nfs_serv.c
> --- nfs/nfs_serv.c  29 Apr 2016 14:40:36 -  1.108
> +++ nfs/nfs_serv.c  3 Jul 2016 18:00:54 -
> @@ -1163,7 +1163,12 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
> pool_put(_pool, nd.ni_cnd.cn_pnbuf);
> error = NFSERR_BADTYPE;
> VOP_ABORTOP(nd.ni_dvp, _cnd);
> -   vput(nd.ni_dvp);
> +   if (nd.ni_dvp == nd.ni_vp)
> +   vrele(nd.ni_dvp);
> +   else
> +   vput(nd.ni_dvp);
> +   if (nd.ni_vp)
> +   vput(nd.ni_vp);
> goto out;
> }
> VATTR_NULL();
> @@ -1185,7 +1190,11 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
> pool_put(_pool, nd.ni_cnd.cn_pnbuf);
> error = EEXIST;
> VOP_ABORTOP(nd.ni_dvp, _cnd);
> -   vput(nd.ni_dvp);
> +   if (nd.ni_dvp == nd.ni_vp)
> +   vrele(nd.ni_dvp);
> +   else
> +   vput(nd.ni_dvp);
> +   vput(nd.ni_vp);
> goto out;
> }
> va.va_type = vtyp;



Re: nfsrv_mknod(): missing vput() in error path

2016-07-03 Thread Martin Natano
FWIW, this is the diff I used to simulate the race condition (only for
testing):

Index: kern/vfs_syscalls.c
===
RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.260
diff -u -p -r1.260 vfs_syscalls.c
--- kern/vfs_syscalls.c 3 Jul 2016 04:36:08 -   1.260
+++ kern/vfs_syscalls.c 3 Jul 2016 19:09:24 -
@@ -1233,9 +1233,12 @@ domknodat(struct proc *p, int fd, const 
if ((error = namei()) != 0)
return (error);
vp = nd.ni_vp;
-   if (vp != NULL)
-   error = EEXIST;
-   else {
+   if (vp != NULL) {
+   /* error = EEXIST; */
+   error = 0;
+   vrele(vp);
+   }
+   /* else { */
VATTR_NULL();
vattr.va_mode = (mode & ALLPERMS) &~ p->p_fd->fd_cmask;
if ((p->p_p->ps_flags & PS_PLEDGE))
@@ -1267,7 +1270,7 @@ domknodat(struct proc *p, int fd, const 
error = EINVAL;
break;
}
-   }
+   /* } */
if (!error) {
error = VOP_MKNOD(nd.ni_dvp, _vp, _cnd, );
} else {


On Sun, Jul 03, 2016 at 09:16:26PM +0200, Martin Natano wrote:
> When perfoming a mknod operation over NFS it can happen that another
> client creates a file with the same name between the namei() and
> VOP_MKNOD() calls in domknod(). This leads to an error path in
> nfsrv_mknod() being triggered. In that error path there is a
> vput(nd.ni_np) missing, resulting in the vnode getting stuck with a
> stale reference and lock, while it shouldn't have either.
> 
> Ok?
> 
> natano
> 
> 
> Index: nfs/nfs_serv.c
> ===
> RCS file: /cvs/src/sys/nfs/nfs_serv.c,v
> retrieving revision 1.108
> diff -u -p -r1.108 nfs_serv.c
> --- nfs/nfs_serv.c29 Apr 2016 14:40:36 -  1.108
> +++ nfs/nfs_serv.c3 Jul 2016 18:00:54 -
> @@ -1163,7 +1163,12 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
>   pool_put(_pool, nd.ni_cnd.cn_pnbuf);
>   error = NFSERR_BADTYPE;
>   VOP_ABORTOP(nd.ni_dvp, _cnd);
> - vput(nd.ni_dvp);
> + if (nd.ni_dvp == nd.ni_vp)
> + vrele(nd.ni_dvp);
> + else
> + vput(nd.ni_dvp);
> + if (nd.ni_vp)
> + vput(nd.ni_vp);
>   goto out;
>   }
>   VATTR_NULL();
> @@ -1185,7 +1190,11 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
>   pool_put(_pool, nd.ni_cnd.cn_pnbuf);
>   error = EEXIST;
>   VOP_ABORTOP(nd.ni_dvp, _cnd);
> - vput(nd.ni_dvp);
> + if (nd.ni_dvp == nd.ni_vp)
> + vrele(nd.ni_dvp);
> + else
> + vput(nd.ni_dvp);
> + vput(nd.ni_vp);
>   goto out;
>   }
>   va.va_type = vtyp;



nfsrv_mknod(): missing vput() in error path

2016-07-03 Thread Martin Natano
When perfoming a mknod operation over NFS it can happen that another
client creates a file with the same name between the namei() and
VOP_MKNOD() calls in domknod(). This leads to an error path in
nfsrv_mknod() being triggered. In that error path there is a
vput(nd.ni_np) missing, resulting in the vnode getting stuck with a
stale reference and lock, while it shouldn't have either.

Ok?

natano


Index: nfs/nfs_serv.c
===
RCS file: /cvs/src/sys/nfs/nfs_serv.c,v
retrieving revision 1.108
diff -u -p -r1.108 nfs_serv.c
--- nfs/nfs_serv.c  29 Apr 2016 14:40:36 -  1.108
+++ nfs/nfs_serv.c  3 Jul 2016 18:00:54 -
@@ -1163,7 +1163,12 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
pool_put(_pool, nd.ni_cnd.cn_pnbuf);
error = NFSERR_BADTYPE;
VOP_ABORTOP(nd.ni_dvp, _cnd);
-   vput(nd.ni_dvp);
+   if (nd.ni_dvp == nd.ni_vp)
+   vrele(nd.ni_dvp);
+   else
+   vput(nd.ni_dvp);
+   if (nd.ni_vp)
+   vput(nd.ni_vp);
goto out;
}
VATTR_NULL();
@@ -1185,7 +1190,11 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
pool_put(_pool, nd.ni_cnd.cn_pnbuf);
error = EEXIST;
VOP_ABORTOP(nd.ni_dvp, _cnd);
-   vput(nd.ni_dvp);
+   if (nd.ni_dvp == nd.ni_vp)
+   vrele(nd.ni_dvp);
+   else
+   vput(nd.ni_dvp);
+   vput(nd.ni_vp);
goto out;
}
va.va_type = vtyp;



Re: rcs: support -I

2016-07-03 Thread Jeremie Courreges-Anglas
"Todd C. Miller"  writes:

> The -I flag is documented but not implemented.  This fixes that and
> also honors the -I flag from ci/co when prompting as per GNU rcs.

Looks correct & works fine here, ok jca@

-- 
jca | PGP: 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE



Re: convert rtadvd to libevent

2016-07-03 Thread Jeremie Courreges-Anglas
j...@wxcvbn.org (Jeremie Courreges-Anglas) writes:

> Custom timers go away, ra_timer_update's signature is simplified.  The
> diff also includes the ctime changes proposed in a standalone diff.
> The rescheduling of the next RA in rs_input() is probably the least
> trivial part.
>
> Comments / oks?

Updated diff.  Always evtimer_add/del for timers, for consistency.

Note that aside from comments (or oks), test reports are welcome!

Index: Makefile
===
RCS file: /cvs/src/usr.sbin/rtadvd/Makefile,v
retrieving revision 1.8
diff -u -p -r1.8 Makefile
--- Makefile30 Nov 2015 20:52:28 -  1.8
+++ Makefile29 Jun 2016 14:42:34 -
@@ -1,9 +1,12 @@
 #  $OpenBSD: Makefile,v 1.8 2015/11/30 20:52:28 jca Exp $
 
 PROG=  rtadvd
-SRCS=  rtadvd.c advcap.c if.c config.c timer.c dump.c log.c
+SRCS=  rtadvd.c advcap.c if.c config.c dump.c log.c
 
 CFLAGS+=-Wall
 MAN=   rtadvd.8 rtadvd.conf.5
+
+LDADD= -levent
+DPADD+=${LIBEVENT}
 
 .include 
Index: config.c
===
RCS file: /cvs/src/usr.sbin/rtadvd/config.c,v
retrieving revision 1.57
diff -u -p -r1.57 config.c
--- config.c29 Jun 2016 14:19:38 -  1.57
+++ config.c1 Jul 2016 23:33:11 -
@@ -55,10 +55,10 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rtadvd.h"
 #include "advcap.h"
-#include "timer.h"
 #include "if.h"
 #include "config.h"
 #include "log.h"
@@ -520,10 +520,7 @@ getconfig(char *intface)
make_packet(tmp);
 
/* set timer */
-   tmp->timer = rtadvd_add_timer(ra_timeout, ra_timer_update,
- tmp, tmp);
-   ra_timer_update(tmp, >timer->tm);
-   rtadvd_set_timer(>timer->tm, tmp->timer);
+   ra_timer_update(tmp);
 }
 
 void
@@ -654,8 +651,7 @@ make_prefix(struct rainfo *rai, int ifin
 * reset the timer so that the new prefix will be advertised quickly.
 */
rai->initcounter = 0;
-   ra_timer_update(rai, >timer->tm);
-   rtadvd_set_timer(>timer->tm, rai->timer);
+   ra_timer_update(rai);
 }
 
 /*
Index: dump.c
===
RCS file: /cvs/src/usr.sbin/rtadvd/dump.c,v
retrieving revision 1.20
diff -u -p -r1.20 dump.c
--- dump.c  29 Jun 2016 14:19:38 -  1.20
+++ dump.c  1 Jul 2016 23:33:11 -
@@ -51,9 +51,9 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rtadvd.h"
-#include "timer.h"
 #include "if.h"
 #include "log.h"
 #include "dump.h"
@@ -108,9 +108,10 @@ rtadvd_dump(void)
struct dnssldom *dnsd;
char prefixbuf[INET6_ADDRSTRLEN];
int first;
-   struct timeval now;
+   struct timeval now, next;
char *origin, *vltime, *pltime, *flags;
char *vltimexpire=NULL, *pltimexpire=NULL;
+   char ctimebuf[26];
 
gettimeofday(, NULL);
SLIST_FOREACH(rai, , entry) {
@@ -122,12 +123,15 @@ rtadvd_dump(void)
/* control information */
if (rai->lastsent.tv_sec) {
time_t t = rai->lastsent.tv_sec;
-   /* note that ctime() appends CR by itself */
-   log_info("  Last RA sent: %s", ctime());
+   (void)strlcpy(ctimebuf, ctime(), sizeof(ctimebuf));
+   ctimebuf[strcspn(ctimebuf, "\n")] = '\0';
+   log_info("  Last RA sent: %s", ctimebuf);
}
-   if (rai->timer) {
-   time_t t = rai->timer->tm.tv_sec;
-   log_info("  Next RA will be sent: %s", ctime());
+   if (evtimer_pending(>timer.ev, )) {
+   time_t t = next.tv_sec;
+   (void)strlcpy(ctimebuf, ctime(), sizeof(ctimebuf));
+   ctimebuf[strcspn(ctimebuf, "\n")] = '\0';
+   log_info("  Next RA will be sent: %s", ctimebuf);
} else
log_info("  RA timer is stopped");
log_info("  waits: %u, initcount: %u",
Index: if.c
===
RCS file: /cvs/src/usr.sbin/rtadvd/if.c,v
retrieving revision 1.40
diff -u -p -r1.40 if.c
--- if.c29 Jun 2016 14:19:38 -  1.40
+++ if.c1 Jul 2016 23:33:11 -
@@ -46,6 +46,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rtadvd.h"
 #include "if.h"
Index: rtadvd.c
===
RCS file: /cvs/src/usr.sbin/rtadvd/rtadvd.c,v
retrieving revision 1.75
diff -u -p -r1.75 rtadvd.c
--- rtadvd.c30 Jun 2016 10:17:18 -  1.75
+++ rtadvd.c3 Jul 2016 17:29:05 -
@@ -49,16 +49,15 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 
 #include "rtadvd.h"
 #include "advcap.h"
-#include "timer.h"
 #include "if.h"
 #include 

iwm: set tx aggregation limit to 1

2016-07-03 Thread Stefan Sperling
I'm not sure if this change has any real effect, but as long as we don't
support 11n TX aggregation it's probably better to set the firmware's
aggregation limit to 1 frame (which means 'no aggregation').

Index: if_iwm.c
===
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.92
diff -u -p -r1.92 if_iwm.c
--- if_iwm.c22 Jun 2016 11:32:12 -  1.92
+++ if_iwm.c3 Jul 2016 12:21:03 -
@@ -6154,7 +6154,11 @@ iwm_setrates(struct iwm_node *in)
 
lq->agg_time_limit = htole16(4000); /* 4ms */
lq->agg_disable_start_th = 3;
+#ifdef notyet
lq->agg_frame_cnt_limit = 0x3f;
+#else
+   lq->agg_frame_cnt_limit = 1; /* tx agg disabled */
+#endif
 
cmd.data[0] = >in_lq;
if (iwm_send_cmd(sc, ) != 0) {



iwm: fix inverted logic

2016-07-03 Thread Stefan Sperling
This code in iwm is supposed to match what Linux does.
The Linux code looks like this:

if (ieee80211_is_data(fc) && len > mvm->rts_threshold &&
!is_multicast_ether_addr(ieee80211_get_DA(hdr)))
tx_flags |= TX_CMD_FLG_PROT_REQUIRE;

Our driver had the 'is data' check inverted since the beginning.

Index: if_iwm.c
===
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.92
diff -u -p -r1.92 if_iwm.c
--- if_iwm.c22 Jun 2016 11:32:12 -  1.92
+++ if_iwm.c3 Jul 2016 09:15:24 -
@@ -4516,7 +4516,7 @@ iwm_tx(struct iwm_softc *sc, struct mbuf
flags |= IWM_TX_CMD_FLG_ACK;
}
 
-   if (type != IEEE80211_FC0_TYPE_DATA
+   if (type == IEEE80211_FC0_TYPE_DATA
&& (totlen + IEEE80211_CRC_LEN > ic->ic_rtsthreshold)
&& !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
flags |= IWM_TX_CMD_FLG_PROT_REQUIRE;



show current tx rate for associated nodes

2016-07-03 Thread Stefan Sperling
For hostap interfaces, ifconfig scan currently shows the maximum supported
Rx Rate or RX MCS of associated stations. E.g. for an iwn(4) device associated
to an athn(4) AP in 11g mode, the AP will show 'HT-MCS7' in ifconfig scan:

  # ifconfig athn0 scan | grep 34:13:e8:d0:60:a9
  lladdr 34:13:e8:d0:60:a9 77dBm HT-MCS7 short_preamble,short_slottime assoc

It shows that 'HT-MCS7' is the maximum supported rate by iwn(4).
Showing the maximum supported rate makes sense when searching for APs.
But on an AP it is more useful to show the current Tx rate our AP is
using to send frames to the associated node.
The diff below implements this, and we get:

  # ifconfig athn0 scan | grep 34:13:e8:d0:60:a9
  lladdr 34:13:e8:d0:60:a9 80dBm 24M short_preamble,short_slottime assoc

Requires ifconfig to be recompiled to run on the new kernel.

Index: sbin/ifconfig/ifconfig.c
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.324
diff -u -p -r1.324 ifconfig.c
--- sbin/ifconfig/ifconfig.c15 Jun 2016 19:39:33 -  1.324
+++ sbin/ifconfig/ifconfig.c3 Jul 2016 12:59:05 -
@@ -2341,8 +2341,19 @@ ieee80211_printnode(struct ieee80211_nod
 
if (nr->nr_pwrsave)
printf("powersave ");
-   /* Only print the fastest rate */
-   if (nr->nr_max_rxrate) {
+   /* 
+* Print our current Tx rate for associated nodes.
+* Print the fastest supported rate for APs.
+*/
+   if ((nr->nr_flags & (IEEE80211_NODEREQ_AP)) == 0) {
+   if (nr->nr_flags & IEEE80211_NODEREQ_HT) {
+   printf("HT-MCS%d ", nr->nr_txmcs);
+   } else if (nr->nr_rates) {
+   printf("%uM ",
+   (nr->nr_rates[nr->nr_txrate] & IEEE80211_RATE_VAL)
+   / 2);
+   }
+   } else if (nr->nr_max_rxrate) {
printf("%uM HT ", nr->nr_max_rxrate);
} else if (nr->nr_rxmcs[0] != 0) {
for (i = IEEE80211_HT_NUM_MCS - 1; i >= 0; i--) {
@@ -2351,9 +2362,8 @@ ieee80211_printnode(struct ieee80211_nod
}
printf("HT-MCS%d ", i);
} else if (nr->nr_nrates) {
-   printf("%uM",
+   printf("%uM ",
(nr->nr_rates[nr->nr_nrates - 1] & IEEE80211_RATE_VAL) / 2);
-   putchar(' ');
}
/* ESS is the default, skip it */
nr->nr_capinfo &= ~IEEE80211_CAPINFO_ESS;
Index: sys/net80211/ieee80211_ioctl.c
===
RCS file: /cvs/src/sys/net80211/ieee80211_ioctl.c,v
retrieving revision 1.41
diff -u -p -r1.41 ieee80211_ioctl.c
--- sys/net80211/ieee80211_ioctl.c  28 Apr 2016 13:50:14 -  1.41
+++ sys/net80211/ieee80211_ioctl.c  3 Jul 2016 13:00:32 -
@@ -112,6 +112,9 @@ ieee80211_node2req(struct ieee80211com *
memcpy(nr->nr_rxmcs, ni->ni_rxmcs, sizeof(nr->nr_rxmcs));
nr->nr_max_rxrate = ni->ni_max_rxrate;
nr->nr_tx_mcs_set = ni->ni_tx_mcs_set;
+   nr->nr_txmcs = ni->ni_txmcs;
+   if (ni->ni_flags & IEEE80211_NODE_HT)
+   nr->nr_flags |= IEEE80211_NODEREQ_HT;
 }
 
 void
Index: sys/net80211/ieee80211_ioctl.h
===
RCS file: /cvs/src/sys/net80211/ieee80211_ioctl.h,v
retrieving revision 1.26
diff -u -p -r1.26 ieee80211_ioctl.h
--- sys/net80211/ieee80211_ioctl.h  28 Apr 2016 14:46:10 -  1.26
+++ sys/net80211/ieee80211_ioctl.h  3 Jul 2016 12:58:58 -
@@ -339,6 +339,7 @@ struct ieee80211_nodereq {
uint8_t nr_rxmcs[howmany(80,NBBY)];
uint16_tnr_max_rxrate;  /* in Mb/s, 0 <= rate <= 1023 */
uint8_t nr_tx_mcs_set;
+   uint8_t nr_txmcs;
 };
 
 #define IEEE80211_NODEREQ_STATE(_s)(1 << _s)
@@ -352,6 +353,7 @@ struct ieee80211_nodereq {
 #define IEEE80211_NODEREQ_AP   0x01/* access point */
 #define IEEE80211_NODEREQ_AP_BSS   0x02/* current bss access point */
 #define IEEE80211_NODEREQ_COPY 0x04/* add node with flags */
+#define IEEE80211_NODEREQ_HT   0x08/* HT negotiated */
 
 #define SIOCG80211NODE _IOWR('i', 211, struct ieee80211_nodereq)
 #define SIOCS80211NODE  _IOW('i', 212, struct ieee80211_nodereq)



rcs: support -I

2016-07-03 Thread Todd C. Miller
The -I flag is documented but not implemented.  This fixes that and
also honors the -I flag from ci/co when prompting as per GNU rcs.

 - todd

Index: usr.bin/rcs/ci.c
===
RCS file: /cvs/src/usr.bin/rcs/ci.c,v
retrieving revision 1.223
diff -u -p -u -r1.223 ci.c
--- usr.bin/rcs/ci.c2 Nov 2015 16:45:21 -   1.223
+++ usr.bin/rcs/ci.c3 Jul 2016 13:18:14 -
@@ -279,7 +279,7 @@ checkin_main(int argc, char **argv)
errx(1, "failed to open rcsfile `%s'", pb.fpath);
 
if ((pb.flags & DESCRIPTION) &&
-   rcs_set_description(pb.file, pb.description) == -1)
+   rcs_set_description(pb.file, pb.description, pb.flags) == 
-1)
err(1, "%s", pb.filename);
 
if (!(pb.flags & QUIET))
@@ -406,7 +406,7 @@ checkin_getlogmsg(RCSNUM *rev, RCSNUM *r
(void)fprintf(stderr, "new revision: %s; "
"previous revision: %s\n", nrev, prev);
 
-   rcs_msg = rcs_prompt(prompt);
+   rcs_msg = rcs_prompt(prompt, flags);
 
return (rcs_msg);
 }
@@ -621,7 +621,7 @@ checkin_init(struct checkin_params *pb)
 
/* Get description from user */
if (pb->description == NULL &&
-   rcs_set_description(pb->file, NULL) == -1) {
+   rcs_set_description(pb->file, NULL, pb->flags) == -1) {
warn("%s", pb->filename);
return (-1);
}
Index: usr.bin/rcs/rcsprog.c
===
RCS file: /cvs/src/usr.bin/rcs/rcsprog.c,v
retrieving revision 1.160
diff -u -p -u -r1.160 rcsprog.c
--- usr.bin/rcs/rcsprog.c   29 Dec 2015 19:12:56 -  1.160
+++ usr.bin/rcs/rcsprog.c   3 Jul 2016 13:17:32 -
@@ -35,7 +35,7 @@
 
 #include "rcsprog.h"
 
-#define RCSPROG_OPTSTRING  "A:a:b::c:e::ik:Ll::m:Mn:N:o:qt::TUu::Vx::z::"
+#define RCSPROG_OPTSTRING  "A:a:b::c:e::Iik:Ll::m:Mn:N:o:qt::TUu::Vx::z::"
 
 const char rcs_version[] = "OpenRCS 4.5";
 
@@ -222,6 +222,9 @@ rcs_main(int argc, char **argv)
elist = rcs_optarg;
rcsflags |= RCSPROG_EFLAG;
break;
+   case 'I':
+   rcsflags |= INTERACTIVE;
+   break;
case 'i':
flags |= RCS_CREATE;
break;
@@ -324,14 +327,14 @@ rcs_main(int argc, char **argv)
}
 
if (rcsflags & DESCRIPTION) {
-   if (rcs_set_description(file, descfile) == -1) {
+   if (rcs_set_description(file, descfile, rcsflags) == 
-1) {
warn("%s", descfile);
rcs_close(file);
continue;
}
}
else if (flags & RCS_CREATE) {
-   if (rcs_set_description(file, NULL) == -1) {
+   if (rcs_set_description(file, NULL, rcsflags) == -1) {
warn("stdin");
rcs_close(file);
continue;
Index: usr.bin/rcs/rcsutil.c
===
RCS file: /cvs/src/usr.bin/rcs/rcsutil.c,v
retrieving revision 1.44
diff -u -p -u -r1.44 rcsutil.c
--- usr.bin/rcs/rcsutil.c   13 Jun 2015 20:15:21 -  1.44
+++ usr.bin/rcs/rcsutil.c   3 Jul 2016 13:15:50 -
@@ -330,16 +330,19 @@ rcs_getrevnum(const char *rev_str, RCSFI
  * Returns the string's pointer.
  */
 char *
-rcs_prompt(const char *prompt)
+rcs_prompt(const char *prompt, int flags)
 {
BUF *bp;
size_t len;
char *buf;
 
+   if (!(flags & INTERACTIVE) && isatty(STDIN_FILENO))
+   flags |= INTERACTIVE;
+
bp = buf_alloc(0);
-   if (isatty(STDIN_FILENO))
+   if (flags & INTERACTIVE)
(void)fprintf(stderr, "%s", prompt);
-   if (isatty(STDIN_FILENO))
+   if (flags & INTERACTIVE)
(void)fprintf(stderr, ">> ");
clearerr(stdin);
while ((buf = fgetln(stdin, )) != NULL) {
@@ -349,7 +352,7 @@ rcs_prompt(const char *prompt)
else
buf_append(bp, buf, len);
 
-   if (isatty(STDIN_FILENO))
+   if (flags & INTERACTIVE)
(void)fprintf(stderr, ">> ");
}
buf_putc(bp, '\0');
@@ -438,7 +441,7 @@ rcs_rev_select(RCSFILE *file, const char
  * Returns 0 on success, -1 on failure, setting errno.
  */
 int
-rcs_set_description(RCSFILE *file, const char *in)
+rcs_set_description(RCSFILE *file, const char *in, int flags)
 {
BUF *bp;
char *content;
@@ -458,7 +461,7 @@ rcs_set_description(RCSFILE *file, const
content = xstrdup(in + 1);
/* Get description from 

Re: malloc.conf: better docs and impl for J/J

2016-07-03 Thread Otto Moerbeek
On Sat, Jul 02, 2016 at 01:17:10PM -0400, Ted Unangst wrote:

> Otto Moerbeek wrote:
> > Hi,
> > 
> > J/j is actually a three valued var. So document that and make it
> > possible to set all three values. Default is still 1.
> 
> I initially left the default as is deliberately. I would like for there to be
> fewer options, because I think people spend too much mental effort picking the
> "right" setting. We should be spending that effort making the default the best
> it can be.
> 
> In this case, I'm not sure how or why the user would want to set it 1. It
> starts at 1. If you like it, don't change it. If you don't like it, change it
> to 0 or 2. 

A case is: you have a malloc.conf with S or J, and you want to run a
single program with the default using MALLOC_OPTIONS to hunt a bug.
Currently there's no way to do that.

-Otto