diff options
Diffstat (limited to 'lib')
34 files changed, 1514 insertions, 238 deletions
diff --git a/lib/Makefile b/lib/Makefile index a3321af9aed0..38003b8fec67 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -75,7 +75,7 @@ SUBDIR= ${SUBDIR_ORDERED} \ ${_libnetgraph} \ ${_libngatm} \ libnv \ - libohash \ + libopenbsd \ libopie \ libpam \ libpcap \ diff --git a/lib/libc/net/getnameinfo.c b/lib/libc/net/getnameinfo.c index c81318926ba1..4b7aecbc6f02 100644 --- a/lib/libc/net/getnameinfo.c +++ b/lib/libc/net/getnameinfo.c @@ -122,7 +122,8 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, afd = find_afd(sa->sa_family); if (afd == NULL) return (EAI_FAMILY); - if (sa->sa_family == PF_LOCAL) { + switch (sa->sa_family) { + case PF_LOCAL: /* * PF_LOCAL uses variable sa->sa_len depending on the * content length of sun_path. Require 1 byte in @@ -132,8 +133,17 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, salen <= afd->a_socklen - sizeofmember(struct sockaddr_un, sun_path)) return (EAI_FAIL); - } else if (salen != afd->a_socklen) - return (EAI_FAIL); + break; + case PF_LINK: + if (salen <= afd->a_socklen - + sizeofmember(struct sockaddr_dl, sdl_data)) + return (EAI_FAIL); + break; + default: + if (salen != afd->a_socklen) + return (EAI_FAIL); + break; + } return ((*afd->a_func)(afd, sa, salen, host, hostlen, serv, servlen, flags)); diff --git a/lib/libc/rpc/clnt_bcast.c b/lib/libc/rpc/clnt_bcast.c index 7242aa4b68df..a194ba6c77cc 100644 --- a/lib/libc/rpc/clnt_bcast.c +++ b/lib/libc/rpc/clnt_bcast.c @@ -636,13 +636,10 @@ rpc_broadcast_exp(rpcprog_t prog, rpcvers_t vers, rpcproc_t proc, } /* The giant for loop */ done_broad: - if (inbuf) - (void) free(inbuf); - if (outbuf) - (void) free(outbuf); + free(inbuf); + free(outbuf); #ifdef PORTMAP - if (outbuf_pmap) - (void) free(outbuf_pmap); + free(outbuf_pmap); #endif /* PORTMAP */ for (i = 0; i < fdlistno; i++) { (void)_close(fdlist[i].fd); diff --git a/lib/libc/rpc/clnt_vc.c b/lib/libc/rpc/clnt_vc.c index e463165069dd..aa16b9690a0b 100644 --- a/lib/libc/rpc/clnt_vc.c +++ b/lib/libc/rpc/clnt_vc.c @@ -651,8 +651,7 @@ clnt_vc_destroy(CLIENT *cl) (void)_close(ct->ct_fd); } XDR_DESTROY(&(ct->ct_xdrs)); - if (ct->ct_addr.buf) - free(ct->ct_addr.buf); + free(ct->ct_addr.buf); mem_free(ct, sizeof(struct ct_data)); if (cl->cl_netid && cl->cl_netid[0]) mem_free(cl->cl_netid, strlen(cl->cl_netid) +1); diff --git a/lib/libc/rpc/getnetconfig.c b/lib/libc/rpc/getnetconfig.c index c1e22da52e46..6d668bf5c2fc 100644 --- a/lib/libc/rpc/getnetconfig.c +++ b/lib/libc/rpc/getnetconfig.c @@ -164,8 +164,7 @@ __nc_error(void) if ((nc_addr = (int *)thr_getspecific(nc_key)) == NULL) { nc_addr = (int *)malloc(sizeof (int)); if (thr_setspecific(nc_key, (void *) nc_addr) != 0) { - if (nc_addr) - free(nc_addr); + free(nc_addr); return (&nc_error); } *nc_addr = 0; @@ -417,7 +416,7 @@ endnetconfig(void *handlep) while (q != NULL) { p = q->next; - if (q->ncp->nc_lookups != NULL) free(q->ncp->nc_lookups); + free(q->ncp->nc_lookups); free(q->ncp); free(q->linep); free(q); @@ -537,8 +536,7 @@ freenetconfigent(struct netconfig *netconfigp) { if (netconfigp != NULL) { free(netconfigp->nc_netid); /* holds all netconfigp's strings */ - if (netconfigp->nc_lookups != NULL) - free(netconfigp->nc_lookups); + free(netconfigp->nc_lookups); free(netconfigp); } return; @@ -628,8 +626,7 @@ parse_ncp(char *stringp, struct netconfig *ncp) } else { char *cp; /* tmp string */ - if (ncp->nc_lookups != NULL) /* from last visit */ - free(ncp->nc_lookups); + free(ncp->nc_lookups); /* from last visit */ ncp->nc_lookups = NULL; ncp->nc_nlookups = 0; while ((cp = tokenp) != NULL) { diff --git a/lib/libc/rpc/mt_misc.c b/lib/libc/rpc/mt_misc.c index 2e17c27f444c..0ec4d8a8b79d 100644 --- a/lib/libc/rpc/mt_misc.c +++ b/lib/libc/rpc/mt_misc.c @@ -106,8 +106,7 @@ __rpc_createerr(void) rce_addr = (struct rpc_createerr *) malloc(sizeof (struct rpc_createerr)); if (thr_setspecific(rce_key, (void *) rce_addr) != 0) { - if (rce_addr) - free(rce_addr); + free(rce_addr); return (&rpc_createerr); } memset(rce_addr, 0, sizeof (struct rpc_createerr)); diff --git a/lib/libc/rpc/rpc_soc.c b/lib/libc/rpc/rpc_soc.c index 8fc91ffde304..11fc80302a12 100644 --- a/lib/libc/rpc/rpc_soc.c +++ b/lib/libc/rpc/rpc_soc.c @@ -432,8 +432,7 @@ clntunix_create(struct sockaddr_un *raddr, u_long prog, u_long vers, int *sockp, if ((raddr->sun_len == 0) || ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { - if (svcaddr != NULL) - free(svcaddr); + free(svcaddr); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; return(cl); diff --git a/lib/libc/rpc/rpcb_clnt.c b/lib/libc/rpc/rpcb_clnt.c index d53d908fc2e4..49300ed37db0 100644 --- a/lib/libc/rpc/rpcb_clnt.c +++ b/lib/libc/rpc/rpcb_clnt.c @@ -179,8 +179,7 @@ delete_cache(struct netbuf *addr) free(cptr->ac_netid); free(cptr->ac_taddr->buf); free(cptr->ac_taddr); - if (cptr->ac_uaddr) - free(cptr->ac_uaddr); + free(cptr->ac_uaddr); if (prevptr) prevptr->ac_next = cptr->ac_next; else @@ -216,14 +215,10 @@ add_cache(const char *host, const char *netid, struct netbuf *taddr, ad_cache->ac_taddr->buf = (char *) malloc(taddr->len); if (ad_cache->ac_taddr->buf == NULL) { out: - if (ad_cache->ac_host) - free(ad_cache->ac_host); - if (ad_cache->ac_netid) - free(ad_cache->ac_netid); - if (ad_cache->ac_uaddr) - free(ad_cache->ac_uaddr); - if (ad_cache->ac_taddr) - free(ad_cache->ac_taddr); + free(ad_cache->ac_host); + free(ad_cache->ac_netid); + free(ad_cache->ac_uaddr); + free(ad_cache->ac_taddr); free(ad_cache); return; } @@ -256,8 +251,7 @@ out: free(cptr->ac_netid); free(cptr->ac_taddr->buf); free(cptr->ac_taddr); - if (cptr->ac_uaddr) - free(cptr->ac_uaddr); + free(cptr->ac_uaddr); if (prevptr) { prevptr->ac_next = NULL; @@ -798,10 +792,8 @@ __rpcb_findaddr_timed(rpcprog_t program, rpcvers_t version, malloc(remote.len)) == NULL)) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; clnt_geterr(client, &rpc_createerr.cf_error); - if (address) { - free(address); - address = NULL; - } + free(address); + address = NULL; goto error; } memcpy(address->buf, remote.buf, remote.len); diff --git a/lib/libc/rpc/svc.c b/lib/libc/rpc/svc.c index 38cbb797f83e..d68fa9f83319 100644 --- a/lib/libc/rpc/svc.c +++ b/lib/libc/rpc/svc.c @@ -198,8 +198,7 @@ svc_reg(SVCXPRT *xprt, const rpcprog_t prog, const rpcvers_t vers, rwlock_wrlock(&svc_lock); if ((s = svc_find(prog, vers, &prev, netid)) != NULL) { - if (netid) - free(netid); + free(netid); if (s->sc_dispatch == dispatch) goto rpcb_it; /* he is registering another xptr */ rwlock_unlock(&svc_lock); @@ -207,8 +206,7 @@ svc_reg(SVCXPRT *xprt, const rpcprog_t prog, const rpcvers_t vers, } s = mem_alloc(sizeof (struct svc_callout)); if (s == NULL) { - if (netid) - free(netid); + free(netid); rwlock_unlock(&svc_lock); return (FALSE); } diff --git a/lib/libc/rpc/svc_dg.c b/lib/libc/rpc/svc_dg.c index 1957d64b4ea3..5d9baaa81f66 100644 --- a/lib/libc/rpc/svc_dg.c +++ b/lib/libc/rpc/svc_dg.c @@ -406,8 +406,7 @@ svc_dg_destroy(SVCXPRT *xprt) (void) mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.maxlen); if (xprt->xp_ltaddr.buf) (void) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen); - if (xprt->xp_tp) - (void) free(xprt->xp_tp); + free(xprt->xp_tp); svc_xprt_free(xprt); } diff --git a/lib/libc/rpc/svc_simple.c b/lib/libc/rpc/svc_simple.c index 4713efcfc558..9ce3f8d4efbc 100644 --- a/lib/libc/rpc/svc_simple.c +++ b/lib/libc/rpc/svc_simple.c @@ -166,10 +166,8 @@ rpc_reg(rpcprog_t prognum, rpcvers_t versnum, rpcproc_t procnum, if (((xdrbuf = malloc((unsigned)recvsz)) == NULL) || ((netid = strdup(nconf->nc_netid)) == NULL)) { warnx(rpc_reg_err, rpc_reg_msg, __no_mem_str); - if (xdrbuf != NULL) - free(xdrbuf); - if (netid != NULL) - free(netid); + free(xdrbuf); + free(netid); SVC_DESTROY(svcxprt); break; } diff --git a/lib/libc/rpc/svc_vc.c b/lib/libc/rpc/svc_vc.c index ca4b93e4fbf7..bafb725696f2 100644 --- a/lib/libc/rpc/svc_vc.c +++ b/lib/libc/rpc/svc_vc.c @@ -394,10 +394,8 @@ __svc_vc_dodestroy(SVCXPRT *xprt) mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.maxlen); if (xprt->xp_ltaddr.buf) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen); - if (xprt->xp_tp) - free(xprt->xp_tp); - if (xprt->xp_netid) - free(xprt->xp_netid); + free(xprt->xp_tp); + free(xprt->xp_netid); svc_xprt_free(xprt); } diff --git a/lib/libc/tests/c063/Makefile b/lib/libc/tests/c063/Makefile index 2e4565cdf318..05da6ea212a9 100644 --- a/lib/libc/tests/c063/Makefile +++ b/lib/libc/tests/c063/Makefile @@ -2,21 +2,21 @@ #TODO: t_o_search -NETBSD_ATF_TESTS_C= faccessat -NETBSD_ATF_TESTS_C+= fchmodat -NETBSD_ATF_TESTS_C+= fchownat -NETBSD_ATF_TESTS_C+= fexecve -NETBSD_ATF_TESTS_C+= fstatat -NETBSD_ATF_TESTS_C+= linkat -NETBSD_ATF_TESTS_C+= mkdirat -NETBSD_ATF_TESTS_C+= mkfifoat -NETBSD_ATF_TESTS_C+= mknodat -NETBSD_ATF_TESTS_C+= openat -NETBSD_ATF_TESTS_C+= readlinkat -NETBSD_ATF_TESTS_C+= renameat -NETBSD_ATF_TESTS_C+= symlinkat -NETBSD_ATF_TESTS_C+= unlinkat -NETBSD_ATF_TESTS_C+= utimensat +NETBSD_ATF_TESTS_C= faccessat_test +NETBSD_ATF_TESTS_C+= fchmodat_test +NETBSD_ATF_TESTS_C+= fchownat_test +NETBSD_ATF_TESTS_C+= fexecve_test +NETBSD_ATF_TESTS_C+= fstatat_test +NETBSD_ATF_TESTS_C+= linkat_test +NETBSD_ATF_TESTS_C+= mkdirat_test +NETBSD_ATF_TESTS_C+= mkfifoat_test +NETBSD_ATF_TESTS_C+= mknodat_test +NETBSD_ATF_TESTS_C+= openat_test +NETBSD_ATF_TESTS_C+= readlinkat_test +NETBSD_ATF_TESTS_C+= renameat_test +NETBSD_ATF_TESTS_C+= symlinkat_test +NETBSD_ATF_TESTS_C+= unlinkat_test +NETBSD_ATF_TESTS_C+= utimensat_test CFLAGS+= -D_INCOMPLETE_XOPEN_C063 diff --git a/lib/libc/tests/setjmp/Makefile b/lib/libc/tests/setjmp/Makefile index 0ca25774beef..ac962c2d8d6d 100644 --- a/lib/libc/tests/setjmp/Makefile +++ b/lib/libc/tests/setjmp/Makefile @@ -1,10 +1,10 @@ # $FreeBSD$ -NETBSD_ATF_TESTS_C= t_setjmp -NETBSD_ATF_TESTS_C+= t_threadjmp +NETBSD_ATF_TESTS_C= setjmp_test +NETBSD_ATF_TESTS_C+= threadjmp_test -DPADD.t_threadjmp+= ${LIBPTHREAD} -LDADD.t_threadjmp+= -lpthread +DPADD.threadjmp_test+= ${LIBPTHREAD} +LDADD.threadjmp_test+= -lpthread WARNS?= 4 diff --git a/lib/libc/tests/string/Makefile b/lib/libc/tests/string/Makefile index d91af08a27f1..fc9c1af4ded4 100644 --- a/lib/libc/tests/string/Makefile +++ b/lib/libc/tests/string/Makefile @@ -4,28 +4,28 @@ # TODO: popcount, stresep -NETBSD_ATF_TESTS_C+= memchr -NETBSD_ATF_TESTS_C+= memcpy -NETBSD_ATF_TESTS_C+= memmem -NETBSD_ATF_TESTS_C+= memset -NETBSD_ATF_TESTS_C+= strcat -NETBSD_ATF_TESTS_C+= strchr -NETBSD_ATF_TESTS_C+= strcmp -NETBSD_ATF_TESTS_C+= strcpy -NETBSD_ATF_TESTS_C+= strcspn -NETBSD_ATF_TESTS_C+= strerror -NETBSD_ATF_TESTS_C+= strlen -NETBSD_ATF_TESTS_C+= strpbrk -NETBSD_ATF_TESTS_C+= strrchr -NETBSD_ATF_TESTS_C+= strspn -NETBSD_ATF_TESTS_C+= swab +NETBSD_ATF_TESTS_C+= memchr_test +NETBSD_ATF_TESTS_C+= memcpy_test +NETBSD_ATF_TESTS_C+= memmem_test +NETBSD_ATF_TESTS_C+= memset_test +NETBSD_ATF_TESTS_C+= strcat_test +NETBSD_ATF_TESTS_C+= strchr_test +NETBSD_ATF_TESTS_C+= strcmp_test +NETBSD_ATF_TESTS_C+= strcpy_test +NETBSD_ATF_TESTS_C+= strcspn_test +NETBSD_ATF_TESTS_C+= strerror_test +NETBSD_ATF_TESTS_C+= strlen_test +NETBSD_ATF_TESTS_C+= strpbrk_test +NETBSD_ATF_TESTS_C+= strrchr_test +NETBSD_ATF_TESTS_C+= strspn_test +NETBSD_ATF_TESTS_C+= swab_test .include "../Makefile.netbsd-tests" -LDADD.memchr+= -lmd -DPADD.memchr+= ${LIBMD} +LDADD.memchr_test+= -lmd +DPADD.memchr_test+= ${LIBMD} -LDADD.memcpy+= -lmd -DPADD.memcpy+= ${LIBMD} +LDADD.memcpy_test+= -lmd +DPADD.memcpy_test+= ${LIBMD} .include <bsd.test.mk> diff --git a/lib/libc/tests/tls_dso/Makefile b/lib/libc/tests/tls_dso/Makefile index b37ffec76659..5449799de96c 100644 --- a/lib/libc/tests/tls_dso/Makefile +++ b/lib/libc/tests/tls_dso/Makefile @@ -1,7 +1,5 @@ # $FreeBSD$ -SRCDIR= ${SRCTOP}/contrib/netbsd/ - .include <bsd.own.mk> LIB= h_tls_dynamic diff --git a/lib/libdpv/dialogrc.c b/lib/libdpv/dialogrc.c index eb4a53621084..e199d415c539 100644 --- a/lib/libdpv/dialogrc.c +++ b/lib/libdpv/dialogrc.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2013-2014 Devin Teske <dteske@FreeBSD.org> + * Copyright (c) 2013-2015 Devin Teske <dteske@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,58 +49,58 @@ char gauge_color[STR_BUFSIZE] = "47b"; /* (BLUE,WHITE,ON) */ char separator[STR_BUFSIZE] = ""; /* Function prototypes */ -static int setattr(struct fp_config *, uint32_t, char *, char *); -static int setbool(struct fp_config *, uint32_t, char *, char *); -static int setnum(struct fp_config *, uint32_t, char *, char *); -static int setstr(struct fp_config *, uint32_t, char *, char *); +static int setattr(struct figpar_config *, uint32_t, char *, char *); +static int setbool(struct figpar_config *, uint32_t, char *, char *); +static int setnum(struct figpar_config *, uint32_t, char *, char *); +static int setstr(struct figpar_config *, uint32_t, char *, char *); /* * Anatomy of DIALOGRC (~/.dialogrc by default) * NOTE: Must appear after private function prototypes (above) * NB: Brace-initialization of union requires cast to *first* member of union */ -static struct fp_config dialogrc_config[] = { - /* TYPE Directive DEFAULT HANDLER */ - {FP_TYPE_INT, "aspect", {(void *)0}, &setnum}, - {FP_TYPE_STR, "separate_widget", {separator}, &setstr}, - {FP_TYPE_INT, "tab_len", {(void *)0}, &setnum}, - {FP_TYPE_BOOL, "visit_items", {(void *)0}, &setbool}, - {FP_TYPE_BOOL, "use_shadow", {(void *)1}, &setbool}, - {FP_TYPE_BOOL, "use_colors", {(void *)1}, &setbool}, - {FP_TYPE_STR, "screen_color", {NULL}, &setattr}, - {FP_TYPE_STR, "shadow_color", {NULL}, &setattr}, - {FP_TYPE_STR, "dialog_color", {NULL}, &setattr}, - {FP_TYPE_STR, "title_color", {NULL}, &setattr}, - {FP_TYPE_STR, "border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_active_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_inactive_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_key_active_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_key_inactive_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_label_active_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_label_inactive_color",{NULL}, &setattr}, - {FP_TYPE_STR, "inputbox_color", {NULL}, &setattr}, - {FP_TYPE_STR, "inputbox_border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "searchbox_color", {NULL}, &setattr}, - {FP_TYPE_STR, "searchbox_title_color", {NULL}, &setattr}, - {FP_TYPE_STR, "searchbox_border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "position_indicator_color", {NULL}, &setattr}, - {FP_TYPE_STR, "menubox_color", {NULL}, &setattr}, - {FP_TYPE_STR, "menubox_border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "item_color", {NULL}, &setattr}, - {FP_TYPE_STR, "item_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_key_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_key_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "check_color", {NULL}, &setattr}, - {FP_TYPE_STR, "check_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "uarrow_color", {NULL}, &setattr}, - {FP_TYPE_STR, "darrow_color", {NULL}, &setattr}, - {FP_TYPE_STR, "itemhelp_color", {NULL}, &setattr}, - {FP_TYPE_STR, "form_active_text_color", {NULL}, &setattr}, - {FP_TYPE_STR, "form_text_color", {NULL}, &setattr}, - {FP_TYPE_STR, "form_item_readonly_color", {NULL}, &setattr}, - {FP_TYPE_STR, "gauge_color", {gauge_color}, &setattr}, +static struct figpar_config dialogrc_config[] = { + /* TYPE DIRECTIVE DEFAULT HANDLER */ + {FIGPAR_TYPE_INT, "aspect", {(void *)0}, &setnum}, + {FIGPAR_TYPE_STR, "separate_widget", {separator}, &setstr}, + {FIGPAR_TYPE_INT, "tab_len", {(void *)0}, &setnum}, + {FIGPAR_TYPE_BOOL, "visit_items", {(void *)0}, &setbool}, + {FIGPAR_TYPE_BOOL, "use_shadow", {(void *)1}, &setbool}, + {FIGPAR_TYPE_BOOL, "use_colors", {(void *)1}, &setbool}, + {FIGPAR_TYPE_STR, "screen_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "shadow_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "dialog_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "title_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "border_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_active_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_inactive_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_key_active_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_key_inactive_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_label_active_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "button_label_inactive_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "inputbox_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "inputbox_border_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "searchbox_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "searchbox_title_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "searchbox_border_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "position_indicator_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "menubox_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "menubox_border_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "item_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "item_selected_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "tag_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "tag_selected_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "tag_key_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "tag_key_selected_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "check_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "check_selected_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "uarrow_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "darrow_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "itemhelp_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "form_active_text_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "form_text_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "form_item_readonly_color", {NULL}, &setattr}, + {FIGPAR_TYPE_STR, "gauge_color", {gauge_color}, &setattr}, {0, NULL, {0}, NULL} }; @@ -108,7 +108,7 @@ static struct fp_config dialogrc_config[] = { * figpar call-back for interpreting value as .dialogrc `Attribute' */ static int -setattr(struct fp_config *option, uint32_t line __unused, +setattr(struct figpar_config *option, uint32_t line __unused, char *directive __unused, char *value) { char *cp = value; @@ -204,7 +204,7 @@ write_attrbuf: * figpar call-back for interpreting value as .dialogrc `Boolean' */ static int -setbool(struct fp_config *option, uint32_t line __unused, +setbool(struct figpar_config *option, uint32_t line __unused, char *directive __unused, char *value) { @@ -227,7 +227,7 @@ setbool(struct fp_config *option, uint32_t line __unused, * figpar call-back for interpreting value as .dialogrc `Number' */ static int -setnum(struct fp_config *option, uint32_t line __unused, +setnum(struct figpar_config *option, uint32_t line __unused, char *directive __unused, char *value) { @@ -247,7 +247,7 @@ setnum(struct fp_config *option, uint32_t line __unused, * figpar call-back for interpreting value as .dialogrc `String' */ static int -setstr(struct fp_config *option, uint32_t line __unused, +setstr(struct figpar_config *option, uint32_t line __unused, char *directive __unused, char *value) { size_t len; @@ -315,7 +315,8 @@ parse_dialogrc(void) } /* Process file (either $DIALOGRC if set, or `$HOME/.dialogrc') */ - res = parse_config(dialogrc_config, path, NULL, FP_BREAK_ON_EQUALS); + res = parse_config(dialogrc_config, + path, NULL, FIGPAR_BREAK_ON_EQUALS); /* Set some globals based on what we parsed */ use_shadow = dialogrc_config_option("use_shadow")->value.boolean; @@ -328,10 +329,10 @@ parse_dialogrc(void) /* * Return a pointer to the `.dialogrc' config option specific to `directive' or - * static fp_dummy_config (full of NULLs) if none found (see + * static figpar_dummy_config (full of NULLs) if none found (see * get_config_option(3); part of figpar(3)). */ -struct fp_config * +struct figpar_config * dialogrc_config_option(const char *directive) { return (get_config_option(dialogrc_config, directive)); diff --git a/lib/libdpv/dialogrc.h b/lib/libdpv/dialogrc.h index 7d1723584d51..a2eb1fbc24aa 100644 --- a/lib/libdpv/dialogrc.h +++ b/lib/libdpv/dialogrc.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2013-2014 Devin Teske <dteske@FreeBSD.org> + * Copyright (c) 2013-2015 Devin Teske <dteske@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,7 +50,7 @@ extern char separator[]; __BEGIN_DECLS void dialogrc_free(void); int parse_dialogrc(void); -struct fp_config *dialogrc_config_option(const char *_directive); +struct figpar_config *dialogrc_config_option(const char *_directive); __END_DECLS #endif /* !_DIALOGRC_H_ */ diff --git a/lib/libfigpar/figpar.3 b/lib/libfigpar/figpar.3 index 8fd49d37c43e..60ab2b50eb85 100644 --- a/lib/libfigpar/figpar.3 +++ b/lib/libfigpar/figpar.3 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Oct 22, 2015 +.Dd Nov 2, 2015 .Dt FIGPAR 3 .Os .Sh NAME @@ -38,13 +38,13 @@ .In figpar.h .Ft int .Fo parse_config -.Fa "struct fp_config options[], const char *path" -.Fa "int \*[lp]*unknown\*[rp]\*[lp]struct fp_config *option, uint32_t line" +.Fa "struct figpar_config options[], const char *path" +.Fa "int \*[lp]*unknown\*[rp]\*[lp]struct figpar_config *option, uint32_t line" .Fa "char *directive, char *value\*[rp], uint8_t processing_options" .Fc -.Ft "struct fp_config *" +.Ft "struct figpar_config *" .Fo get_config_option -.Fa "struct fp_config options[], const char *directive" +.Fa "struct figpar_config options[], const char *directive" .Fc .In string_m.h .Ft int @@ -91,32 +91,32 @@ Configuration directives, types, and callback functions are provided through data structures defined in .In figpar.h : .Bd -literal -offset indent -struct fp_config { - enum fp_cfgtype type; /* value type */ - const char *directive; /* keyword */ - union fp_cfgvalue value; /* value */ +struct figpar_config { + enum figpar_cfgtype type; /* value type */ + const char *directive; /* keyword */ + union figpar_cfgvalue value; /* value */ /* Pointer to function used when directive is found */ - int (*action)(struct fp_config *option, uint32_t line, + int (*action)(struct figpar_config *option, uint32_t line, char *directive, char *value); }; -enum fp_cfgtype { - FP_TYPE_NONE = 0x0000, /* for directives with no value */ - FP_TYPE_BOOL = 0x0001, /* boolean */ - FP_TYPE_INT = 0x0002, /* signed 32 bit integer */ - FP_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ - FP_TYPE_STR = 0x0008, /* string pointer */ - FP_TYPE_STRARRAY = 0x0010, /* string array pointer */ - FP_TYPE_DATA1 = 0x0020, /* void data type-1 (whatever) */ - FP_TYPE_DATA2 = 0x0040, /* void data type-2 (whatever) */ - FP_TYPE_DATA3 = 0x0080, /* void data type-3 (whatever) */ - FP_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 (future) */ - FP_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 (future) */ - FP_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 (future) */ +enum figpar_cfgtype { + FIGPAR_TYPE_NONE = 0x0000, /* directives with no value */ + FIGPAR_TYPE_BOOL = 0x0001, /* boolean */ + FIGPAR_TYPE_INT = 0x0002, /* signed 32 bit integer */ + FIGPAR_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ + FIGPAR_TYPE_STR = 0x0008, /* string pointer */ + FIGPAR_TYPE_STRARRAY = 0x0010, /* string array pointer */ + FIGPAR_TYPE_DATA1 = 0x0020, /* void data type-1 (open) */ + FIGPAR_TYPE_DATA2 = 0x0040, /* void data type-2 (open) */ + FIGPAR_TYPE_DATA3 = 0x0080, /* void data type-3 (open) */ + FIGPAR_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 */ + FIGPAR_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 */ + FIGPAR_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 */ }; -union fp_cfgvalue { +union figpar_cfgvalue { void *data; /* Pointer to NUL-terminated string */ char *str; /* Pointer to NUL-terminated string */ char **strarray; /* Pointer to an array of strings */ @@ -133,26 +133,26 @@ argument to is a mask of bit fields which indicate various processing options. The possible flags are as follows: -.Bl -tag -width FP_BREAK_ON_SEMICOLON -.It Dv FP_BREAK_ON_EQUALS +.Bl -tag -width FIGPAR_BREAK_ON_SEMICOLON +.It Dv FIGPAR_BREAK_ON_EQUALS An equals sign .Pq Ql Li = is normally considered part of the directive. This flag enables terminating the directive at the equals sign. Also makes equals sign optional and transient. -.It Dv FP_BREAK_ON_SEMICOLON +.It Dv FIGPAR_BREAK_ON_SEMICOLON A semicolon .Pq Ql Li \; is normally considered part of the value. This flag enables terminating the value at the semicolon. Also allows multiple statements on a single line separated by semicolon. -.It Dv FP_CASE_SENSITIVE +.It Dv FIGPAR_CASE_SENSITIVE Normally directives are matched case insensitively using .Xr fnmatch 3 . This flag enables directive matching to be case sensitive. -.It Dv FP_REQUIRE_EQUALS +.It Dv FIGPAR_REQUIRE_EQUALS If a directive is not followed by an equals, processing is aborted. -.It Dv FP_STRICT_EQUALS +.It Dv FIGPAR_STRICT_EQUALS Equals must be part of the directive to be considered a delimiter between directive and value. .El @@ -163,14 +163,14 @@ struct array pointer can be NULL and every directive will invoke the .Fn unknown function argument. .Pp -The directive for each fp_config item in the +The directive for each figpar_config item in the .Fn parse_config options argument is matched against each parsed directive using .Xr fnmatch 3 until a match is found. If a match is found, the .Fn action -function for that fp_config directive is invoked with the line number, +function for that figpar_config directive is invoked with the line number, directive, and value. Otherwise if no match, the .Fn unknown @@ -192,11 +192,11 @@ or if no match a pointer to a static dummy struct is returned .Pq whose values are all zero or NULL . .Pp The use of -.Fa "struct fp_config" +.Fa "struct figpar_config" is entirely optional as-is the use of -.Fa "enum fp_cfgtype" +.Fa "enum figpar_cfgtype" or -.Fa "union fp_cfgvalue" . +.Fa "union figpar_cfgvalue" . For example, you could choose to pass a NULL pointer to .Fn parse_config for the first argument and then provide a simple diff --git a/lib/libfigpar/figpar.c b/lib/libfigpar/figpar.c index a97fc85e9097..0a727ff6f041 100644 --- a/lib/libfigpar/figpar.c +++ b/lib/libfigpar/figpar.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002-2014 Devin Teske <dteske@FreeBSD.org> + * Copyright (c) 2002-2015 Devin Teske <dteske@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,24 +40,25 @@ __FBSDID("$FreeBSD$"); #include "figpar.h" #include "string_m.h" -struct fp_config fp_dummy_config = {0, NULL, {0}, NULL}; +struct figpar_config figpar_dummy_config = {0, NULL, {0}, NULL}; /* - * Search for config option (struct fp_config) in the array of config options, - * returning the struct whose directive matches the given parameter. If no - * match is found, a pointer to the static dummy array (above) is returned. + * Search for config option (struct figpar_config) in the array of config + * options, returning the struct whose directive matches the given parameter. + * If no match is found, a pointer to the static dummy array (above) is + * returned. * * This is to eliminate dependency on the index position of an item in the * array, since the index position is more apt to be changed as code grows. */ -struct fp_config * -get_config_option(struct fp_config options[], const char *directive) +struct figpar_config * +get_config_option(struct figpar_config options[], const char *directive) { uint32_t n; /* Check arguments */ if (options == NULL || directive == NULL) - return (&fp_dummy_config); + return (&figpar_dummy_config); /* Loop through the array, return the index of the first match */ for (n = 0; options[n].directive != NULL; n++) @@ -65,12 +66,12 @@ get_config_option(struct fp_config options[], const char *directive) return (&(options[n])); /* Re-initialize the dummy variable in case it was written to */ - fp_dummy_config.directive = NULL; - fp_dummy_config.type = 0; - fp_dummy_config.action = NULL; - fp_dummy_config.value.u_num = 0; + figpar_dummy_config.directive = NULL; + figpar_dummy_config.type = 0; + figpar_dummy_config.action = NULL; + figpar_dummy_config.value.u_num = 0; - return (&fp_dummy_config); + return (&figpar_dummy_config); } /* @@ -84,9 +85,9 @@ get_config_option(struct fp_config options[], const char *directive) * Returns zero on success; otherwise returns -1 and errno should be consulted. */ int -parse_config(struct fp_config options[], const char *path, - int (*unknown)(struct fp_config *option, uint32_t line, char *directive, - char *value), uint16_t processing_options) +parse_config(struct figpar_config options[], const char *path, + int (*unknown)(struct figpar_config *option, uint32_t line, + char *directive, char *value), uint16_t processing_options) { uint8_t bequals; uint8_t bsemicolon; @@ -119,11 +120,15 @@ parse_config(struct fp_config options[], const char *path, return (-1); /* Processing options */ - bequals = (processing_options & FP_BREAK_ON_EQUALS) == 0 ? 0 : 1; - bsemicolon = (processing_options & FP_BREAK_ON_SEMICOLON) == 0 ? 0 : 1; - case_sensitive = (processing_options & FP_CASE_SENSITIVE) == 0 ? 0 : 1; - require_equals = (processing_options & FP_REQUIRE_EQUALS) == 0 ? 0 : 1; - strict_equals = (processing_options & FP_STRICT_EQUALS) == 0 ? 0 : 1; + bequals = (processing_options & FIGPAR_BREAK_ON_EQUALS) == 0 ? 0 : 1; + bsemicolon = + (processing_options & FIGPAR_BREAK_ON_SEMICOLON) == 0 ? 0 : 1; + case_sensitive = + (processing_options & FIGPAR_CASE_SENSITIVE) == 0 ? 0 : 1; + require_equals = + (processing_options & FIGPAR_REQUIRE_EQUALS) == 0 ? 0 : 1; + strict_equals = + (processing_options & FIGPAR_STRICT_EQUALS) == 0 ? 0 : 1; /* Initialize strings */ directive = value = 0; diff --git a/lib/libfigpar/figpar.h b/lib/libfigpar/figpar.h index 16f825a88502..f2dc45b288ae 100644 --- a/lib/libfigpar/figpar.h +++ b/lib/libfigpar/figpar.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002-2014 Devin Teske <dteske@FreeBSD.org> + * Copyright (c) 2002-2015 Devin Teske <dteske@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ /* * Union for storing various types of data in a single common container. */ -union fp_cfgvalue { +union figpar_cfgvalue { void *data; /* Pointer to NUL-terminated string */ char *str; /* Pointer to NUL-terminated string */ char **strarray; /* Pointer to an array of strings */ @@ -46,53 +46,53 @@ union fp_cfgvalue { /* * Option types (based on above cfgvalue union) */ -enum fp_cfgtype { - FP_TYPE_NONE = 0x0000, /* for directives with no value */ - FP_TYPE_BOOL = 0x0001, /* boolean */ - FP_TYPE_INT = 0x0002, /* signed 32 bit integer */ - FP_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ - FP_TYPE_STR = 0x0008, /* string pointer */ - FP_TYPE_STRARRAY = 0x0010, /* string array pointer */ - FP_TYPE_DATA1 = 0x0020, /* void data type-1 (whatever) */ - FP_TYPE_DATA2 = 0x0040, /* void data type-2 (whatever) */ - FP_TYPE_DATA3 = 0x0080, /* void data type-3 (whatever) */ - FP_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 (future) */ - FP_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 (future) */ - FP_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 (future) */ +enum figpar_cfgtype { + FIGPAR_TYPE_NONE = 0x0000, /* directives with no value */ + FIGPAR_TYPE_BOOL = 0x0001, /* boolean */ + FIGPAR_TYPE_INT = 0x0002, /* signed 32 bit integer */ + FIGPAR_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ + FIGPAR_TYPE_STR = 0x0008, /* string pointer */ + FIGPAR_TYPE_STRARRAY = 0x0010, /* string array pointer */ + FIGPAR_TYPE_DATA1 = 0x0020, /* void data type-1 (open) */ + FIGPAR_TYPE_DATA2 = 0x0040, /* void data type-2 (open) */ + FIGPAR_TYPE_DATA3 = 0x0080, /* void data type-3 (open) */ + FIGPAR_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 */ + FIGPAR_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 */ + FIGPAR_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 */ }; /* * Options to parse_config() for processing_options bitmask */ -#define FP_BREAK_ON_EQUALS 0x0001 /* stop reading directive at `=' */ -#define FP_BREAK_ON_SEMICOLON 0x0002 /* `;' starts a new line */ -#define FP_CASE_SENSITIVE 0x0004 /* directives are case sensitive */ -#define FP_REQUIRE_EQUALS 0x0008 /* assignment directives only */ -#define FP_STRICT_EQUALS 0x0010 /* `=' must be part of directive */ +#define FIGPAR_BREAK_ON_EQUALS 0x0001 /* stop reading directive at `=' */ +#define FIGPAR_BREAK_ON_SEMICOLON 0x0002 /* `;' starts a new line */ +#define FIGPAR_CASE_SENSITIVE 0x0004 /* directives are case sensitive */ +#define FIGPAR_REQUIRE_EQUALS 0x0008 /* assignment directives only */ +#define FIGPAR_STRICT_EQUALS 0x0010 /* `=' must be part of directive */ /* * Anatomy of a config file option */ -struct fp_config { - enum fp_cfgtype type; /* Option value type */ +struct figpar_config { + enum figpar_cfgtype type; /* Option value type */ const char *directive; /* config file keyword */ - union fp_cfgvalue value; /* NB: set by action */ + union figpar_cfgvalue value; /* NB: set by action */ /* * Function pointer; action to be taken when the directive is found */ - int (*action)(struct fp_config *option, uint32_t line, char *directive, - char *value); + int (*action)(struct figpar_config *option, uint32_t line, + char *directive, char *value); }; -extern struct fp_config fp_dummy_config; +extern struct figpar_config figpar_dummy_config; __BEGIN_DECLS -int parse_config(struct fp_config _options[], +int parse_config(struct figpar_config _options[], const char *_path, - int (*_unknown)(struct fp_config *_option, + int (*_unknown)(struct figpar_config *_option, uint32_t _line, char *_directive, char *_value), uint16_t _processing_options); -struct fp_config *get_config_option(struct fp_config _options[], +struct figpar_config *get_config_option(struct figpar_config _options[], const char *_directive); __END_DECLS diff --git a/lib/libnetbsd/README b/lib/libnetbsd/README index ab303007cce4..49afa0b436bf 100644 --- a/lib/libnetbsd/README +++ b/lib/libnetbsd/README @@ -2,6 +2,6 @@ $FreeBSD$ libnetbsd is a thin compatibility layer intended to allow a limited set of NetBSD software to compile as part of the FreeBSD build with -little or no modifiction. It is built as a static library and not +little or no modification. It is built as a static library and not installed for general use. Likewise, its header files are not installed. diff --git a/lib/libohash/Makefile b/lib/libopenbsd/Makefile index 198093e289b0..33b9ff0874cb 100644 --- a/lib/libohash/Makefile +++ b/lib/libopenbsd/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -LIB= ohash +LIB= openbsd SRCS= ohash.c INTERNALLIB= diff --git a/lib/libohash/Makefile.depend b/lib/libopenbsd/Makefile.depend index 18be76b0cb6f..18be76b0cb6f 100644 --- a/lib/libohash/Makefile.depend +++ b/lib/libopenbsd/Makefile.depend diff --git a/lib/libopenbsd/README b/lib/libopenbsd/README new file mode 100644 index 000000000000..e9f6d70b5fc5 --- /dev/null +++ b/lib/libopenbsd/README @@ -0,0 +1,7 @@ +$FreeBSD$ + +libopenbsd is a thin compatibility layer intended to allow a limited +set of OpenBSD software to compile as part of the FreeBSD build with +little or no modification. It is built as a static library and not +installed for general use. Likewise, its header files are not +installed. diff --git a/lib/libopenbsd/imsg-buffer.c b/lib/libopenbsd/imsg-buffer.c new file mode 100644 index 000000000000..2ea4d20b9fcd --- /dev/null +++ b/lib/libopenbsd/imsg-buffer.c @@ -0,0 +1,309 @@ +/* $OpenBSD: imsg-buffer.c,v 1.7 2015/07/12 18:40:49 nicm Exp $ */ + +/* + * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/socket.h> +#include <sys/uio.h> + +#include <limits.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "imsg.h" + +int ibuf_realloc(struct ibuf *, size_t); +void ibuf_enqueue(struct msgbuf *, struct ibuf *); +void ibuf_dequeue(struct msgbuf *, struct ibuf *); + +struct ibuf * +ibuf_open(size_t len) +{ + struct ibuf *buf; + + if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) + return (NULL); + if ((buf->buf = malloc(len)) == NULL) { + free(buf); + return (NULL); + } + buf->size = buf->max = len; + buf->fd = -1; + + return (buf); +} + +struct ibuf * +ibuf_dynamic(size_t len, size_t max) +{ + struct ibuf *buf; + + if (max < len) + return (NULL); + + if ((buf = ibuf_open(len)) == NULL) + return (NULL); + + if (max > 0) + buf->max = max; + + return (buf); +} + +int +ibuf_realloc(struct ibuf *buf, size_t len) +{ + u_char *b; + + /* on static buffers max is eq size and so the following fails */ + if (buf->wpos + len > buf->max) { + errno = ERANGE; + return (-1); + } + + b = realloc(buf->buf, buf->wpos + len); + if (b == NULL) + return (-1); + buf->buf = b; + buf->size = buf->wpos + len; + + return (0); +} + +int +ibuf_add(struct ibuf *buf, const void *data, size_t len) +{ + if (buf->wpos + len > buf->size) + if (ibuf_realloc(buf, len) == -1) + return (-1); + + memcpy(buf->buf + buf->wpos, data, len); + buf->wpos += len; + return (0); +} + +void * +ibuf_reserve(struct ibuf *buf, size_t len) +{ + void *b; + + if (buf->wpos + len > buf->size) + if (ibuf_realloc(buf, len) == -1) + return (NULL); + + b = buf->buf + buf->wpos; + buf->wpos += len; + return (b); +} + +void * +ibuf_seek(struct ibuf *buf, size_t pos, size_t len) +{ + /* only allowed to seek in already written parts */ + if (pos + len > buf->wpos) + return (NULL); + + return (buf->buf + pos); +} + +size_t +ibuf_size(struct ibuf *buf) +{ + return (buf->wpos); +} + +size_t +ibuf_left(struct ibuf *buf) +{ + return (buf->max - buf->wpos); +} + +void +ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf) +{ + ibuf_enqueue(msgbuf, buf); +} + +int +ibuf_write(struct msgbuf *msgbuf) +{ + struct iovec iov[IOV_MAX]; + struct ibuf *buf; + unsigned int i = 0; + ssize_t n; + + memset(&iov, 0, sizeof(iov)); + TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { + if (i >= IOV_MAX) + break; + iov[i].iov_base = buf->buf + buf->rpos; + iov[i].iov_len = buf->wpos - buf->rpos; + i++; + } + +again: + if ((n = writev(msgbuf->fd, iov, i)) == -1) { + if (errno == EINTR) + goto again; + if (errno == ENOBUFS) + errno = EAGAIN; + return (-1); + } + + if (n == 0) { /* connection closed */ + errno = 0; + return (0); + } + + msgbuf_drain(msgbuf, n); + + return (1); +} + +void +ibuf_free(struct ibuf *buf) +{ + free(buf->buf); + free(buf); +} + +void +msgbuf_init(struct msgbuf *msgbuf) +{ + msgbuf->queued = 0; + msgbuf->fd = -1; + TAILQ_INIT(&msgbuf->bufs); +} + +void +msgbuf_drain(struct msgbuf *msgbuf, size_t n) +{ + struct ibuf *buf, *next; + + for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; + buf = next) { + next = TAILQ_NEXT(buf, entry); + if (buf->rpos + n >= buf->wpos) { + n -= buf->wpos - buf->rpos; + ibuf_dequeue(msgbuf, buf); + } else { + buf->rpos += n; + n = 0; + } + } +} + +void +msgbuf_clear(struct msgbuf *msgbuf) +{ + struct ibuf *buf; + + while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL) + ibuf_dequeue(msgbuf, buf); +} + +int +msgbuf_write(struct msgbuf *msgbuf) +{ + struct iovec iov[IOV_MAX]; + struct ibuf *buf; + unsigned int i = 0; + ssize_t n; + struct msghdr msg; + struct cmsghdr *cmsg; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; + + memset(&iov, 0, sizeof(iov)); + memset(&msg, 0, sizeof(msg)); + memset(&cmsgbuf, 0, sizeof(cmsgbuf)); + TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { + if (i >= IOV_MAX) + break; + iov[i].iov_base = buf->buf + buf->rpos; + iov[i].iov_len = buf->wpos - buf->rpos; + i++; + if (buf->fd != -1) + break; + } + + msg.msg_iov = iov; + msg.msg_iovlen = i; + + if (buf != NULL && buf->fd != -1) { + msg.msg_control = (caddr_t)&cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = buf->fd; + } + +again: + if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) { + if (errno == EINTR) + goto again; + if (errno == ENOBUFS) + errno = EAGAIN; + return (-1); + } + + if (n == 0) { /* connection closed */ + errno = 0; + return (0); + } + + /* + * assumption: fd got sent if sendmsg sent anything + * this works because fds are passed one at a time + */ + if (buf != NULL && buf->fd != -1) { + close(buf->fd); + buf->fd = -1; + } + + msgbuf_drain(msgbuf, n); + + return (1); +} + +void +ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf) +{ + TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry); + msgbuf->queued++; +} + +void +ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) +{ + TAILQ_REMOVE(&msgbuf->bufs, buf, entry); + + if (buf->fd != -1) + close(buf->fd); + + msgbuf->queued--; + ibuf_free(buf); +} diff --git a/lib/libopenbsd/imsg.c b/lib/libopenbsd/imsg.c new file mode 100644 index 000000000000..cb16bd7c284c --- /dev/null +++ b/lib/libopenbsd/imsg.c @@ -0,0 +1,307 @@ +/* $OpenBSD: imsg.c,v 1.10 2015/07/19 07:18:59 nicm Exp $ */ + +/* + * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/socket.h> +#include <sys/uio.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "imsg.h" + +int imsg_fd_overhead = 0; + +int imsg_get_fd(struct imsgbuf *); + +void +imsg_init(struct imsgbuf *ibuf, int fd) +{ + msgbuf_init(&ibuf->w); + memset(&ibuf->r, 0, sizeof(ibuf->r)); + ibuf->fd = fd; + ibuf->w.fd = fd; + ibuf->pid = getpid(); + TAILQ_INIT(&ibuf->fds); +} + +ssize_t +imsg_read(struct imsgbuf *ibuf) +{ + struct msghdr msg; + struct cmsghdr *cmsg; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int) * 1)]; + } cmsgbuf; + struct iovec iov; + ssize_t n = -1; + int fd; + struct imsg_fd *ifd; + + memset(&msg, 0, sizeof(msg)); + memset(&cmsgbuf, 0, sizeof(cmsgbuf)); + + iov.iov_base = ibuf->r.buf + ibuf->r.wpos; + iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = &cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + + if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL) + return (-1); + +again: + if (getdtablecount() + imsg_fd_overhead + + (CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int) + >= getdtablesize()) { + errno = EAGAIN; + free(ifd); + return (-1); + } + + if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) { + if (errno == EMSGSIZE) + goto fail; + if (errno != EINTR && errno != EAGAIN) + goto fail; + goto again; + } + + ibuf->r.wpos += n; + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + int i; + int j; + + /* + * We only accept one file descriptor. Due to C + * padding rules, our control buffer might contain + * more than one fd, and we must close them. + */ + j = ((char *)cmsg + cmsg->cmsg_len - + (char *)CMSG_DATA(cmsg)) / sizeof(int); + for (i = 0; i < j; i++) { + fd = ((int *)CMSG_DATA(cmsg))[i]; + if (ifd != NULL) { + ifd->fd = fd; + TAILQ_INSERT_TAIL(&ibuf->fds, ifd, + entry); + ifd = NULL; + } else + close(fd); + } + } + /* we do not handle other ctl data level */ + } + +fail: + if (ifd) + free(ifd); + return (n); +} + +ssize_t +imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) +{ + size_t av, left, datalen; + + av = ibuf->r.wpos; + + if (IMSG_HEADER_SIZE > av) + return (0); + + memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr)); + if (imsg->hdr.len < IMSG_HEADER_SIZE || + imsg->hdr.len > MAX_IMSGSIZE) { + errno = ERANGE; + return (-1); + } + if (imsg->hdr.len > av) + return (0); + datalen = imsg->hdr.len - IMSG_HEADER_SIZE; + ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE; + if (datalen == 0) + imsg->data = NULL; + else if ((imsg->data = malloc(datalen)) == NULL) + return (-1); + + if (imsg->hdr.flags & IMSGF_HASFD) + imsg->fd = imsg_get_fd(ibuf); + else + imsg->fd = -1; + + memcpy(imsg->data, ibuf->r.rptr, datalen); + + if (imsg->hdr.len < av) { + left = av - imsg->hdr.len; + memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left); + ibuf->r.wpos = left; + } else + ibuf->r.wpos = 0; + + return (datalen + IMSG_HEADER_SIZE); +} + +int +imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, + pid_t pid, int fd, const void *data, u_int16_t datalen) +{ + struct ibuf *wbuf; + + if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) + return (-1); + + if (imsg_add(wbuf, data, datalen) == -1) + return (-1); + + wbuf->fd = fd; + + imsg_close(ibuf, wbuf); + + return (1); +} + +int +imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, + pid_t pid, int fd, const struct iovec *iov, int iovcnt) +{ + struct ibuf *wbuf; + int i, datalen = 0; + + for (i = 0; i < iovcnt; i++) + datalen += iov[i].iov_len; + + if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) + return (-1); + + for (i = 0; i < iovcnt; i++) + if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1) + return (-1); + + wbuf->fd = fd; + + imsg_close(ibuf, wbuf); + + return (1); +} + +/* ARGSUSED */ +struct ibuf * +imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, + pid_t pid, u_int16_t datalen) +{ + struct ibuf *wbuf; + struct imsg_hdr hdr; + + datalen += IMSG_HEADER_SIZE; + if (datalen > MAX_IMSGSIZE) { + errno = ERANGE; + return (NULL); + } + + hdr.type = type; + hdr.flags = 0; + hdr.peerid = peerid; + if ((hdr.pid = pid) == 0) + hdr.pid = ibuf->pid; + if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) { + return (NULL); + } + if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) + return (NULL); + + return (wbuf); +} + +int +imsg_add(struct ibuf *msg, const void *data, u_int16_t datalen) +{ + if (datalen) + if (ibuf_add(msg, data, datalen) == -1) { + ibuf_free(msg); + return (-1); + } + return (datalen); +} + +void +imsg_close(struct imsgbuf *ibuf, struct ibuf *msg) +{ + struct imsg_hdr *hdr; + + hdr = (struct imsg_hdr *)msg->buf; + + hdr->flags &= ~IMSGF_HASFD; + if (msg->fd != -1) + hdr->flags |= IMSGF_HASFD; + + hdr->len = (u_int16_t)msg->wpos; + + ibuf_close(&ibuf->w, msg); +} + +void +imsg_free(struct imsg *imsg) +{ + free(imsg->data); +} + +int +imsg_get_fd(struct imsgbuf *ibuf) +{ + int fd; + struct imsg_fd *ifd; + + if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL) + return (-1); + + fd = ifd->fd; + TAILQ_REMOVE(&ibuf->fds, ifd, entry); + free(ifd); + + return (fd); +} + +int +imsg_flush(struct imsgbuf *ibuf) +{ + while (ibuf->w.queued) + if (msgbuf_write(&ibuf->w) <= 0) + return (-1); + return (0); +} + +void +imsg_clear(struct imsgbuf *ibuf) +{ + int fd; + + msgbuf_clear(&ibuf->w); + while ((fd = imsg_get_fd(ibuf)) != -1) + close(fd); +} diff --git a/lib/libopenbsd/imsg.h b/lib/libopenbsd/imsg.h new file mode 100644 index 000000000000..10d684736ed2 --- /dev/null +++ b/lib/libopenbsd/imsg.h @@ -0,0 +1,114 @@ +/* $OpenBSD: imsg.h,v 1.3 2013/12/26 17:32:33 eric Exp $ */ + +/* + * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org> + * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org> + * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#ifndef _IMSG_H_ +#define _IMSG_H_ + +#define IBUF_READ_SIZE 65535 +#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) +#define MAX_IMSGSIZE 16384 + +struct ibuf { + TAILQ_ENTRY(ibuf) entry; + u_char *buf; + size_t size; + size_t max; + size_t wpos; + size_t rpos; + int fd; +}; + +struct msgbuf { + TAILQ_HEAD(, ibuf) bufs; + u_int32_t queued; + int fd; +}; + +struct ibuf_read { + u_char buf[IBUF_READ_SIZE]; + u_char *rptr; + size_t wpos; +}; + +struct imsg_fd { + TAILQ_ENTRY(imsg_fd) entry; + int fd; +}; + +struct imsgbuf { + TAILQ_HEAD(, imsg_fd) fds; + struct ibuf_read r; + struct msgbuf w; + int fd; + pid_t pid; +}; + +#define IMSGF_HASFD 1 + +struct imsg_hdr { + u_int32_t type; + u_int16_t len; + u_int16_t flags; + u_int32_t peerid; + u_int32_t pid; +}; + +struct imsg { + struct imsg_hdr hdr; + int fd; + void *data; +}; + + +/* buffer.c */ +struct ibuf *ibuf_open(size_t); +struct ibuf *ibuf_dynamic(size_t, size_t); +int ibuf_add(struct ibuf *, const void *, size_t); +void *ibuf_reserve(struct ibuf *, size_t); +void *ibuf_seek(struct ibuf *, size_t, size_t); +size_t ibuf_size(struct ibuf *); +size_t ibuf_left(struct ibuf *); +void ibuf_close(struct msgbuf *, struct ibuf *); +int ibuf_write(struct msgbuf *); +void ibuf_free(struct ibuf *); +void msgbuf_init(struct msgbuf *); +void msgbuf_clear(struct msgbuf *); +int msgbuf_write(struct msgbuf *); +void msgbuf_drain(struct msgbuf *, size_t); + +/* imsg.c */ +void imsg_init(struct imsgbuf *, int); +ssize_t imsg_read(struct imsgbuf *); +ssize_t imsg_get(struct imsgbuf *, struct imsg *); +int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, + int, const void *, u_int16_t); +int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, + int, const struct iovec *, int); +struct ibuf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, + u_int16_t); +int imsg_add(struct ibuf *, const void *, u_int16_t); +void imsg_close(struct imsgbuf *, struct ibuf *); +void imsg_free(struct imsg *); +int imsg_flush(struct imsgbuf *); +void imsg_clear(struct imsgbuf *); + +#endif diff --git a/lib/libopenbsd/imsg_init.3 b/lib/libopenbsd/imsg_init.3 new file mode 100644 index 000000000000..eb4b1a665d55 --- /dev/null +++ b/lib/libopenbsd/imsg_init.3 @@ -0,0 +1,549 @@ +.\" $OpenBSD: imsg_init.3,v 1.13 2015/07/11 16:23:59 deraadt Exp $ +.\" +.\" Copyright (c) 2010 Nicholas Marriott <nicm@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER +.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" $FreeBSD$ +.\" +.Dd $Mdocdate: July 11 2015 $ +.Dt IMSG_INIT 3 +.Os +.Sh NAME +.Nm imsg_init , +.Nm imsg_read , +.Nm imsg_get , +.Nm imsg_compose , +.Nm imsg_composev , +.Nm imsg_create , +.Nm imsg_add , +.Nm imsg_close , +.Nm imsg_free , +.Nm imsg_flush , +.Nm imsg_clear , +.Nm ibuf_open , +.Nm ibuf_dynamic , +.Nm ibuf_add , +.Nm ibuf_reserve , +.Nm ibuf_seek , +.Nm ibuf_size , +.Nm ibuf_left , +.Nm ibuf_close , +.Nm ibuf_write , +.Nm ibuf_free , +.Nm msgbuf_init , +.Nm msgbuf_clear , +.Nm msgbuf_write , +.Nm msgbuf_drain +.Nd IPC messaging functions +.Sh SYNOPSIS +.In sys/types.h +.In sys/queue.h +.In sys/uio.h +.In imsg.h +.Ft void +.Fn imsg_init "struct imsgbuf *ibuf" "int fd" +.Ft ssize_t +.Fn imsg_read "struct imsgbuf *ibuf" +.Ft ssize_t +.Fn imsg_get "struct imsgbuf *ibuf" "struct imsg *imsg" +.Ft int +.Fn imsg_compose "struct imsgbuf *ibuf" "u_int32_t type" "uint32_t peerid" \ + "pid_t pid" "int fd" "const void *data" "u_int16_t datalen" +.Ft int +.Fn imsg_composev "struct imsgbuf *ibuf" "u_int32_t type" "u_int32_t peerid" \ + "pid_t pid" "int fd" "const struct iovec *iov" "int iovcnt" +.Ft "struct ibuf *" +.Fn imsg_create "struct imsgbuf *ibuf" "u_int32_t type" "u_int32_t peerid" \ + "pid_t pid" "u_int16_t datalen" +.Ft int +.Fn imsg_add "struct ibuf *buf" "const void *data" "u_int16_t datalen" +.Ft void +.Fn imsg_close "struct imsgbuf *ibuf" "struct ibuf *msg" +.Ft void +.Fn imsg_free "struct imsg *imsg" +.Ft int +.Fn imsg_flush "struct imsgbuf *ibuf" +.Ft void +.Fn imsg_clear "struct imsgbuf *ibuf" +.Ft "struct ibuf *" +.Fn ibuf_open "size_t len" +.Ft "struct ibuf *" +.Fn ibuf_dynamic "size_t len" "size_t max" +.Ft int +.Fn ibuf_add "struct ibuf *buf" "const void *data" "size_t len" +.Ft "void *" +.Fn ibuf_reserve "struct ibuf *buf" "size_t len" +.Ft "void *" +.Fn ibuf_seek "struct ibuf *buf" "size_t pos" "size_t len" +.Ft size_t +.Fn ibuf_size "struct ibuf *buf" +.Ft size_t +.Fn ibuf_left "struct ibuf *buf" +.Ft void +.Fn ibuf_close "struct msgbuf *msgbuf" "struct ibuf *buf" +.Ft int +.Fn ibuf_write "struct msgbuf *msgbuf" +.Ft void +.Fn ibuf_free "struct ibuf *buf" +.Ft void +.Fn msgbuf_init "struct msgbuf *msgbuf" +.Ft void +.Fn msgbuf_clear "struct msgbuf *msgbuf" +.Ft int +.Fn msgbuf_write "struct msgbuf *msgbuf" +.Ft void +.Fn msgbuf_drain "struct msgbuf *msgbuf" "size_t n" +.Sh DESCRIPTION +The +.Nm imsg +functions provide a simple mechanism for communication between processes +using sockets. +Each transmitted message is guaranteed to be presented to the receiving program +whole. +They are commonly used in privilege separated processes, where processes with +different rights are required to cooperate. +.Pp +A program using these functions should be linked with +.Em -lutil . +.Pp +The basic +.Nm +structure is the +.Em imsgbuf , +which wraps a file descriptor and represents one side of a channel on which +messages are sent and received: +.Bd -literal -offset indent +struct imsgbuf { + TAILQ_HEAD(, imsg_fd) fds; + struct ibuf_read r; + struct msgbuf w; + int fd; + pid_t pid; +}; +.Ed +.Pp +.Fn imsg_init +is a routine which initializes +.Fa ibuf +as one side of a channel associated with +.Fa fd . +The file descriptor is used to send and receive messages, +but is not closed by any of the imsg functions. +An imsgbuf is initialized with the +.Em w +member as the output buffer queue, +.Em fd +with the file descriptor passed to +.Fn imsg_init +and the other members for internal use only. +.Pp +The +.Fn imsg_clear +function frees any data allocated as part of an imsgbuf. +.Pp +.Fn imsg_create , +.Fn imsg_add +and +.Fn imsg_close +are generic construction routines for messages that are to be sent using an +imsgbuf. +.Pp +.Fn imsg_create +creates a new message with header specified by +.Fa type , +.Fa peerid +and +.Fa pid . +A +.Fa pid +of zero uses the process ID returned by +.Xr getpid 2 +when +.Fa ibuf +was initialized. +In addition to this common imsg header, +.Fa datalen +bytes of space may be reserved for attaching to this imsg. +This space is populated using +.Fn imsg_add . +Additionally, the file descriptor +.Fa fd +may be passed over the socket to the other process. +If +.Fa fd +is given, it is closed in the sending program after the message is sent. +A value of \-1 indicates no file descriptor should be passed. +.Fn imsg_create +returns a pointer to a new message if it succeeds, NULL otherwise. +.Pp +.Fn imsg_add +appends to +.Fa imsg +.Fa len +bytes of ancillary data pointed to by +.Fa buf . +It returns +.Fa len +if it succeeds, \-1 otherwise. +.Pp +.Fn imsg_close +completes creation of +.Fa imsg +by adding it to +.Fa imsgbuf +output buffer. +.Pp +.Fn imsg_compose +is a routine which is used to quickly create and queue an imsg. +It takes the same parameters as the +.Fn imsg_create , +.Fn imsg_add +and +.Fn imsg_close +routines, +except that only one ancillary data buffer can be provided. +This routine returns 1 if it succeeds, \-1 otherwise. +.Pp +.Fn imsg_composev +is similar to +.Fn imsg_compose . +It takes the same parameters, except that the ancillary data buffer is specified +by +.Fa iovec . +.Pp +.Fn imsg_flush +is a function which calls +.Fn msgbuf_write +in a loop until all imsgs in the output buffer are sent. +It returns 0 if it succeeds, \-1 otherwise. +.Pp +The +.Fn imsg_read +routine reads pending data with +.Xr recvmsg 2 +and queues it as individual messages on +.Fa imsgbuf . +It returns the number of bytes read on success, or \-1 on error. +A return value of \-1 from +.Fn imsg_read +invalidates +.Fa imsgbuf , +and renders it suitable only for passing to +.Fn imsg_clear . +.Pp +.Fn imsg_get +fills in an individual imsg pending on +.Fa imsgbuf +into the structure pointed to by +.Fa imsg . +It returns the total size of the message, 0 if no messages are ready, or \-1 +for an error. +Received messages are returned as a +.Em struct imsg , +which must be freed by +.Fn imsg_free +when no longer required. +.Em struct imsg +has this form: +.Bd -literal -offset indent +struct imsg { + struct imsg_hdr hdr; + int fd; + void *data; +}; + +struct imsg_hdr { + u_int32_t type; + u_int16_t len; + u_int16_t flags; + u_int32_t peerid; + u_int32_t pid; +}; +.Ed +.Pp +The header members are: +.Bl -tag -width Ds -offset indent +.It type +A integer identifier, typically used to express the meaning of the message. +.It len +The total length of the imsg, including the header and any ancillary data +transmitted with the message (pointed to by the +.Em data +member of the message itself). +.It flags +Flags used internally by the imsg functions: should not be used by application +programs. +.It peerid, pid +32-bit values specified on message creation and free for any use by the +caller, normally used to identify the message sender. +.El +.Pp +In addition, +.Em struct imsg +has the following: +.Bl -tag -width Ds -offset indent +.It fd +The file descriptor specified when the message was created and passed using the +socket control message API, or \-1 if no file descriptor was sent. +.It data +A pointer to the ancillary data transmitted with the imsg. +.El +.Pp +The IMSG_HEADER_SIZE define is the size of the imsg message header, which +may be subtracted from the +.Fa len +member of +.Em struct imsg_hdr +to obtain the length of any additional data passed with the message. +.Pp +MAX_IMSGSIZE is defined as the maximum size of a single imsg, currently +16384 bytes. +.Sh BUFFERS +The imsg API defines functions to manipulate buffers, used internally and during +construction of imsgs with +.Fn imsg_create . +A +.Em struct ibuf +is a single buffer and a +.Em struct msgbuf +a queue of output buffers for transmission: +.Bd -literal -offset indent +struct ibuf { + TAILQ_ENTRY(ibuf) entry; + u_char *buf; + size_t size; + size_t max; + size_t wpos; + size_t rpos; + int fd; +}; + +struct msgbuf { + TAILQ_HEAD(, ibuf) bufs; + u_int32_t queued; + int fd; +}; +.Ed +.Pp +The +.Fn ibuf_open +function allocates a fixed-length buffer. +The buffer may not be resized and may contain a maximum of +.Fa len +bytes. +On success +.Fn ibuf_open +returns a pointer to the buffer; on failure it returns NULL. +.Pp +.Fn ibuf_dynamic +allocates a resizeable buffer of initial length +.Fa len +and maximum size +.Fa max . +Buffers allocated with +.Fn ibuf_dynamic +are automatically grown if necessary when data is added. +.Pp +.Fn ibuf_add +is a routine which appends a block of data to +.Fa buf . +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_reserve +is used to reserve +.Fa len +bytes in +.Fa buf . +A pointer to the start of the reserved space is returned, or NULL on error. +.Pp +.Fn ibuf_seek +is a function which returns a pointer to the part of the buffer at offset +.Fa pos +and of extent +.Fa len . +NULL is returned if the requested range is outside the part of the buffer +in use. +.Pp +.Fn ibuf_size +and +.Fn ibuf_left +are functions which return the total bytes used and available in +.Fa buf +respectively. +.Pp +.Fn ibuf_close +appends +.Fa buf +to +.Fa msgbuf +ready to be sent. +.Pp +The +.Fn ibuf_write +routine transmits as many pending buffers as possible from +.Fn msgbuf +using +.Xr writev 2 . +It returns 1 if it succeeds, \-1 on error and 0 when no buffers were +pending or an EOF condition on the socket is detected. +Temporary resource shortages are returned with errno +.Er EAGAIN +and require the application to retry again in the future. +.Pp +.Fn ibuf_free +frees +.Fa buf +and any associated storage. +.Pp +The +.Fn msgbuf_init +function initializes +.Fa msgbuf +so that buffers may be appended to it. +The +.Em fd +member should also be set directly before +.Fn msgbuf_write +is used. +.Pp +.Fn msgbuf_clear +empties a msgbuf, removing and discarding any queued buffers. +.Pp +The +.Fn msgbuf_write +routine calls +.Xr sendmsg 2 +to transmit buffers queued in +.Fa msgbuf . +It returns 1 if it succeeds, \-1 on error, and 0 when the queue was empty +or an EOF condition on the socket is detected. +Temporary resource shortages are returned with errno +.Er EAGAIN +and require the application to retry again in the future. +.Pp +.Fn msgbuf_drain +discards data from buffers queued in +.Fa msgbuf +until +.Fa n +bytes have been removed or +.Fa msgbuf +is empty. +.Sh EXAMPLES +In a typical program, a channel between two processes is created with +.Xr socketpair 2 , +and an +.Em imsgbuf +created around one file descriptor in each process: +.Bd -literal -offset indent +struct imsgbuf parent_ibuf, child_ibuf; +int imsg_fds[2]; + +if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) + err(1, "socketpair"); + +switch (fork()) { +case -1: + err(1, "fork"); +case 0: + /* child */ + close(imsg_fds[0]); + imsg_init(&child_ibuf, imsg_fds[1]); + exit(child_main(&child_ibuf)); +} + +/* parent */ +close(imsg_fds[1]); +imsg_init(&parent_ibuf, imsg_fds[0]); +exit(parent_main(&parent_ibuf)); +.Ed +.Pp +Messages may then be composed and queued on the +.Em imsgbuf , +for example using the +.Fn imsg_compose +function: +.Bd -literal -offset indent +enum imsg_type { + IMSG_A_MESSAGE, + IMSG_MESSAGE2 +}; + +int +child_main(struct imsgbuf *ibuf) +{ + int idata; + ... + idata = 42; + imsg_compose(ibuf, IMSG_A_MESSAGE, + 0, 0, -1, &idata, sizeof idata); + ... +} +.Ed +.Pp +A mechanism such as +.Xr poll 2 +or the +.Xr event 3 +library is used to monitor the socket file descriptor. +When the socket is ready for writing, queued messages are transmitted with +.Fn msgbuf_write : +.Bd -literal -offset indent + if (msgbuf_write(&ibuf-\*(Gtw) \*(Lt= 0 && errno != EAGAIN) { + /* handle write failure */ + } +.Ed +.Pp +And when ready for reading, messages are first received using +.Fn imsg_read +and then extracted with +.Fn imsg_get : +.Bd -literal -offset indent +void +dispatch_imsg(struct imsgbuf *ibuf) +{ + struct imsg imsg; + ssize_t n, datalen; + int idata; + + if ((n = imsg_read(ibuf)) == -1 || n == 0) { + /* handle socket error */ + } + + for (;;) { + if ((n = imsg_get(ibuf, &imsg)) == -1) { + /* handle read error */ + } + if (n == 0) /* no more messages */ + return; + datalen = imsg.hdr.len - IMSG_HEADER_SIZE; + + switch (imsg.hdr.type) { + case IMSG_A_MESSAGE: + if (datalen \*(Lt sizeof idata) { + /* handle corrupt message */ + } + memcpy(&idata, imsg.data, sizeof idata); + /* handle message received */ + break; + ... + } + + imsg_free(&imsg); + } +} +.Ed +.Sh SEE ALSO +.Xr socketpair 2 , +.Xr unix 4 diff --git a/lib/libohash/ohash.c b/lib/libopenbsd/ohash.c index 3a0f5dde449c..3a0f5dde449c 100644 --- a/lib/libohash/ohash.c +++ b/lib/libopenbsd/ohash.c diff --git a/lib/libohash/ohash.h b/lib/libopenbsd/ohash.h index ff21c8599ead..ff21c8599ead 100644 --- a/lib/libohash/ohash.h +++ b/lib/libopenbsd/ohash.h diff --git a/lib/libohash/ohash_init.3 b/lib/libopenbsd/ohash_init.3 index 184c4e389b24..184c4e389b24 100644 --- a/lib/libohash/ohash_init.3 +++ b/lib/libopenbsd/ohash_init.3 diff --git a/lib/libohash/ohash_interval.3 b/lib/libopenbsd/ohash_interval.3 index 3809c34e3c0f..3809c34e3c0f 100644 --- a/lib/libohash/ohash_interval.3 +++ b/lib/libopenbsd/ohash_interval.3 diff --git a/lib/libutil/pty.3 b/lib/libutil/pty.3 index f71cc5323d72..0f06cc17811e 100644 --- a/lib/libutil/pty.3 +++ b/lib/libutil/pty.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" " -.Dd December 29, 1996 +.Dd November 11, 2015 .Dt PTY 3 .Os .Sh NAME @@ -120,7 +120,7 @@ function may fail and set the global variable .Dv errno for any of the errors specified for the .Xr grantpt 3 , -.Xr posix_openpt 3 , +.Xr posix_openpt 2 , .Xr ptsname 3 , and .Xr unlockpt 3 |
