mg - set read-only from command line
If I am opening a lot of files into an editor but with the intention of not changing the contents (or more usually only amending a couple of files), a la: > mg * I like to open them all read-only, then change the ones I want to edit to read-write as required, that way I know when I close them all I know that any changes are there because I wanted to make them. Instead of thinking 'did I really want that change' when I'm asked to save a file I didn't want to edit, but edited it accidentally. This diff allows mg to open all command specified files read-only: > mg -R * ok? Mark Index: mg.1 === RCS file: /cvs/src/usr.bin/mg/mg.1,v retrieving revision 1.96 diff -u -p -r1.96 mg.1 --- mg.121 Dec 2015 09:04:52 - 1.96 +++ mg.123 Dec 2015 15:53:03 - @@ -10,6 +10,7 @@ .Sh SYNOPSIS .Nm mg .Op Fl n +.Op Fl R .Op Fl f Ar mode .Op + Ns Ar number .Op Ar @@ -40,6 +41,8 @@ arguments on the command line, including scratch buffer and all files. .It Fl n Turn off backup file generation. +.It Fl R +Files specified on the command line will be opened read-only. .El .Sh WINDOWS AND BUFFERS When a file is loaded into Index: main.c === RCS file: /cvs/src/usr.bin/mg/main.c,v retrieving revision 1.80 diff -u -p -r1.80 main.c --- main.c 19 Nov 2015 19:30:44 - 1.80 +++ main.c 23 Dec 2015 15:53:03 - @@ -53,14 +53,17 @@ main(int argc, char **argv) char*cp, *init_fcn_name = NULL; PF init_fcn = NULL; int o, i, nfiles; - int nobackups = 0; + int nobackups = 0, bro = 0; struct buffer *bp = NULL; if (pledge("stdio rpath wpath cpath fattr getpw tty proc exec", NULL) == -1) err(1, "pledge"); - while ((o = getopt(argc, argv, "nf:")) != -1) + while ((o = getopt(argc, argv, "Rnf:")) != -1) switch (o) { + case 'R': + bro = 1; + break; case 'n': nobackups = 1; break; @@ -170,6 +173,8 @@ notnum: init_fcn(FFOTHARG, 1); nfiles++; } + if (bro) + curbp->b_flag |= BFREADONLY; } } }
fgetwc(3) error reporting bug
Hi, i just noticed a bug in fgetwc(3) in our libc, the function used to implement getwc(3), getwchar(3), getws(3), getwln(3) and the wscanf(3) family of functions. In case of an encoding error, it does not set the error indicator, such that a program correctly checking ferror(3) after WEOF may miss the error. Our manual says: If the stream is at end-of-file or a read error occurs, the routines return WEOF. The routines feof(3) and ferror(3) must be used to distinguish between end-of-file and error. POSIX is even more explicit: If an encoding error occurs, the error indicator for the stream shall be set, fgetwc() shall return WEOF, and shall set errno to indicate the error. Besides, setting errno is pointless; mbrtowc(3) already did that, and the standard requires it to do so. OK? Ingo Index: stdio/fgetwc.c === RCS file: /cvs/src/lib/libc/stdio/fgetwc.c,v retrieving revision 1.5 diff -u -p -r1.5 fgetwc.c --- stdio/fgetwc.c 31 Aug 2015 02:53:57 - 1.5 +++ stdio/fgetwc.c 23 Dec 2015 17:05:42 - @@ -69,7 +69,7 @@ __fgetwc_unlock(FILE *fp) c = ch; size = mbrtowc(, , 1, st); if (size == (size_t)-1) { - errno = EILSEQ; + fp->_flags |= __SERR; return WEOF; } } while (size == (size_t)-2);
Re: Add --brief and --dereference to file(1)
Ralf Horstmannwrites: > Hi, Hi, > xdg-open uses "xdg-mime query filetype" to find out the mime type of a given > file. Depending on the desktop environment, xdg-mime uses different backends. > In my case (i3 wm) it falls back to the generic code path, which uses > > file --brief --dereference --mime-type > > Since --brief and --dereference are not recognized, xdg-mime returns an empty > mime type and causes xdg-open to open the given file with a browser instead of > using the preferred application. That explains a few things... > The following patch adds --brief and --dereference to file(1) to address this. Your patch looks correct and indeed fixes xdg-open here. Nicholas, objections/ok? > Regards, > Ralf > > Index: usr.bin/file/file.1 > === > RCS file: /usr/cvs/openbsd/src/usr.bin/file/file.1,v > retrieving revision 1.43 > diff -u -u -r1.43 file.1 > --- usr.bin/file/file.1 30 Jul 2015 11:13:24 - 1.43 > +++ usr.bin/file/file.1 20 Dec 2015 11:13:37 - > @@ -83,7 +83,7 @@ > .Pp > The options are as follows: > .Bl -tag -width indent > -.It Fl b > +.It Fl b , -brief > Does not prepend filenames to output lines. > .It Fl c > Prints a summary of the parsed magic file; usually used for debugging. > @@ -97,7 +97,7 @@ > .Dq text/plain > rather than > .Dq ASCII text . > -.It Fl L > +.It Fl L , -dereference > Causes symlinks to be followed. > .It Fl s > Attempts to read block and character device files, not just regular files. > Index: usr.bin/file/file.c > === > RCS file: /usr/cvs/openbsd/src/usr.bin/file/file.c,v > retrieving revision 1.56 > diff -u -u -r1.56 file.c > --- usr.bin/file/file.c 5 Dec 2015 13:18:09 - 1.56 > +++ usr.bin/file/file.c 20 Dec 2015 10:50:21 - > @@ -102,9 +102,11 @@ > static FILE *magicfp; > > static struct option longopts[] = { > - { "mime", no_argument, NULL, 'i' }, > - { "mime-type", no_argument, NULL, 'i' }, > - { NULL,0, NULL, 0 } > + { "brief", no_argument, NULL, 'b' }, > + { "dereference", no_argument, NULL, 'L' }, > + { "mime",no_argument, NULL, 'i' }, > + { "mime-type", no_argument, NULL, 'i' }, > + { NULL, 0, NULL, 0 } > }; > > __dead void > -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
Re: UTF-8 support for colrm(1)
Hi Steffen, Steffen Nurpmeso wrote on Wed, Dec 23, 2015 at 11:45:36AM +0100: > Ingo Schwarzewrote: >> For example, colrm(1). >> >> 4. The backspace character (U+0008) backs up by one display position >>rather than by one character. That causes miscounting when >>backspace follows a zero-width or double-width character. > this however is unfortunately common behaviour for terminals, too. Sure, i noticed that in xterm(1) during testing. I neither said that all other software is perfect, nor that mixing backspace encoding with UTF-8 is particularly robust this season. I'm just trying to improve colrm(1) here. Note that making backspace back up by one character is not making anything worse. Sure, xterm(1) displays it badly, but some other programs, for example less(1), already implement the better semantics. So changing additional utilities to also use the better semantics makes the system better and more constistent overall. Telling people to add TWO backpaces after a double width character to please xterm(1) would not be reasonable. It breaks less(1) in an even worse way then using one backspace breaks xterm(1). And then we would have to change less(1) and mandoc(1) and groff(1) and probably more programs, people would have to change their files, and we would have a more awkward and more complicated semantics. So, remember this rule: ++ | Backspace removes the previous character, no matter its width. | ++++++ |||| |||| Yours, Ingo
rdate - truncated error messages
Hello. After the recent addition of pledge and privilege separation to rdate, some error messages get truncated, since the pipe message size for the child is limited to 256. For example: $ rdate -n pool.ntp.org rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign reque Are there any potential issues with increasing the size a little bit? As in: Index: rdate.c === RCS file: /build/openbsd/cvs/src/usr.sbin/rdate/rdate.c,v retrieving revision 1.34 diff -u -p -r1.34 rdate.c --- rdate.c 31 Oct 2015 18:24:01 - 1.34 +++ rdate.c 23 Dec 2015 17:54:00 - @@ -64,7 +64,7 @@ extern char*__progname; __dead voidusage(void); struct { - char message[256]; + char message[1024]; struct timeval new; struct timeval adjust; } pdata; With this change the errors look like this: ZAURUS: /build/openbsd/current/src/usr.sbin/rdate $ obj/rdate -n pool.ntp.org rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Unable to get a reasonable time estimate ZAURUS: /build/openbsd/current/src/usr.sbin/rdate $ obj/rdate -n google.com rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: Can't assign requested address rdate: Failed to connect to server: No route to host rdate: Unable to get a reasonable time estimate
Re: vlan(4): better checks for valid vlan ids
David Gwynne(da...@gwynne.id.au) on 2015.12.22 11:06:21 +1000: > the spec says vlan 0 and vlan 4095 are reserved, so we probably > shouldnt use them. > > this tweaks the vlan tag check only allow valid ids per the spec. > > ok? code reads ok however, this could be tweaked in ifconfig too: 3589: __tag = tag = strtonum(val, 0, 4095, ); i can do that if you commit this (or you do it). > > Index: if_vlan.c > === > RCS file: /cvs/src/sys/net/if_vlan.c,v > retrieving revision 1.150 > diff -u -p -r1.150 if_vlan.c > --- if_vlan.c 8 Dec 2015 11:35:42 - 1.150 > +++ if_vlan.c 22 Dec 2015 01:04:24 - > @@ -156,6 +156,8 @@ vlan_clone_create(struct if_clone *ifc, > else > ifv->ifv_type = ETHERTYPE_VLAN; > > + ifv->ifv_tag = EVL_VLID_MIN; > + > refcnt_init(>ifv_refcnt); > > ifp->if_start = vlan_start; > @@ -586,6 +588,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd > struct ifvlan *ifv; > struct vlanreq vlr; > int error = 0, s; > + uint16_t tag; > > ifr = (struct ifreq *)data; > ifa = (struct ifaddr *)data; > @@ -630,15 +633,18 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd > error = ENOENT; > break; > } > + > /* >* Don't let the caller set up a VLAN tag with >* anything except VLID bits. >*/ > - if (vlr.vlr_tag & ~EVL_VLID_MASK) { > + tag = vlr.vlr_tag; > + if (tag < EVL_VLID_MIN || tag > EVL_VLID_MAX) { > error = EINVAL; > break; > } > - error = vlan_config(ifv, pr, vlr.vlr_tag); > + > + error = vlan_config(ifv, pr, tag); > if (error) > break; > ifp->if_flags |= IFF_RUNNING; > Index: if_vlan_var.h > === > RCS file: /cvs/src/sys/net/if_vlan_var.h,v > retrieving revision 1.31 > diff -u -p -r1.31 if_vlan_var.h > --- if_vlan_var.h 3 Dec 2015 16:27:32 - 1.31 > +++ if_vlan_var.h 22 Dec 2015 01:04:24 - > @@ -42,7 +42,10 @@ struct ether_vlan_header { > u_int16_t evl_proto; > }; > > -#define EVL_VLID_MASK 0x0FFF > +#define EVL_VLID_MASK 0xFFF > +/* 0x000 and 0xFFF are reserved */ > +#define EVL_VLID_MIN0x001 > +#define EVL_VLID_MAX0xFFE > #define EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK) > #define EVL_PRIOFTAG(tag) (((tag) >> EVL_PRIO_BITS) & 7) > #define EVL_ENCAPLEN4 /* length in octets of encapsulation */ > --
Re: UTF-8 support for colrm(1)
Ingo Schwarzewrote: |Steffen Nurpmeso wrote on Wed, Dec 23, 2015 at 11:45:36AM +0100: |> Ingo Schwarze wrote: |>> For example, colrm(1). |>> |>> 4. The backspace character (U+0008) backs up by one display position |>>rather than by one character. That causes miscounting when |>>backspace follows a zero-width or double-width character. | |> this however is unfortunately common behaviour for terminals, too. |So, remember this rule: | | ++ | | Backspace removes the previous character, no matter its width. | | ++++++ | |||| | |||| __ .d$$b .' TO$;\ / : TP._; / _.; :Tb| / / ;j$j _.-" d .' .. d; / /P' dP. |\ / " .d$$$P' |\^"l .' `T$P^" : ._.' _.'; `-.-".-'-' ._. _.-".-" `.-" _ ._ .-" -(.g$$$b. .' ""^^T$$$P^).(: _/ -" /.' /:/; ._.'-'`-' ")/ /;/; `-.-"..--"" " / / ; .-" ..--""-' : ..--""--.-" (\ .-(\ ..--"" `-\(\/;` _. : ;`- :\ ; bug --steffen
Re: Failed to boot after upgrading to Dec. 23 snapshot
This has been fixed by Ken. Thanks! http://marc.info/?l=openbsd-cvs=145088426911767=2 Regards, Glenn
Re: UTF-8 support for colrm(1)
Hello Ingo, Ingo Schwarzewrote: |For example, colrm(1). |4. The backspace character (U+0008) backs up by one display position | rather than by one character. That causes miscounting when | backspace follows a zero-width or double-width character. this however is unfortunately common behaviour for terminals, too. I explicitly misused this misfeature in my N(ail)C(ommand)L(ine editor) commented as * We do not handle character widths because the terminal must deal with that * anyway on the one hand, and also wcwidth(3) doesn't support zero-width * characters by definition on the other. We're addicted. yet noone ever cared. I.e., you see the cursor advancing by two spaces when a double-width glyph is inserted (e.g., xterm, nsterm) but backspace and cub1/le will loose that knowledge! Especially mysterious when then deleting at that position since it'll remove the double-width character and place a space before the cursor! For v14.9 of my thing i'm in the process of warping "NCL" to a new "NLE", the commit message of which will say Use termcap.c abstraction for movement and other such terminal capability related operations instead of unrolling anything ourselfs. As a part of this, honour wcwidth(3): i will never understand why terminals support double-width character insertion and move the cursor accordingly even in non-canonical mode, but fail to deal with that with successive cursor movements or \b. But it is like that so NLE has to deal with it. Finally do. I.e., BS==wcwidth(3)*BS/cub1/le for NLE. But what i'm trying to say is that it seems that for plain \b the ship has sailed a long time ago. --steffen
pledge tokenadm(8)
Hi tech@ tokenadm(8) pretty much needs almost the same pledge annotations as login_token(8), "rpath wpath cpath fattr flock" for operations on the DB files and before that it also needs getpw due to calling getgrnam(3) to get the group (TOKEN_GROUP). In this case where both differ is that tokenadm(8) doesn't call readpassphrase(3) and therefore it doesn't need tty. Any comments? Index: tokenadm.c === RCS file: /cvs/src/usr.sbin/tokenadm/tokenadm.c,v retrieving revision 1.10 diff -u -p -u -r1.10 tokenadm.c --- tokenadm.c 16 Jan 2015 06:40:22 - 1.10 +++ tokenadm.c 23 Dec 2015 22:24:26 - @@ -167,6 +167,9 @@ main(int argc, char **argv) goto usage; } + if (pledge("stdio rpath wpath cpath fattr flock getpw", NULL) == -1) + err(1, "pledge"); + if (what == LIST && (dmode || emode)) what = MODECH;
Re: Make em(4) more mpsafe again
On 11.12.2015. 10:47, Martin Pieuchot wrote: > On 05/12/15(Sat) 15:41, Claudio Jeker wrote: >> So Mark and I spent some time to figure out what the issue was with ix(4) >> based on that info I resurected the em(4) mpsafe diff that got backed out >> and I applied the same fix. It is somewhat unclear if this fixes the >> watchdog timeouts since in theory the wdog timer should be stopped when >> hitting the race condition we hit in ix(4). >> >> I'm currently hammering my test system with this and until now I have not >> seen a watchdog fired. > > It is the right time to get this in. ok mpi@ Hi all, is there any possibility to get this patch in ?
Failed to boot after upgrading to Dec. 23 snapshot
Hi Tech@, After upgrading my system to Dec. 23 snapshot it failed to boot with the following error: Using drive 0, partition 3. Loading. probing: pc0 mem[630K 511M 510M 2471M 4582M a20=on] disk: hd0+ sr0* >> OpenBSD/amd64 BOOT 3.29 Passphrase: open(sr0a:/etc/boot.conf): can't read disk label boot> cannot open sr0a:/etc/random.seed: can't read disk label booting sr0a:/bsd: open sr0a:/bsd: can't read disk label failed(96). will try /bsd boot> I'm using a crypto volume, copied the recent version of bsd.rd into my system and booted into it, upgrade with no error until I rebooted the system. What do I need to do to fix this? Thanks in advance. dmesg from the last snapshot (12/19/2015): OpenBSD 5.8-current (GENERIC.MP) #1757: Sat Dec 19 08:17:18 MST 2015 dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP RTC BIOS diagnostic error 80 real mem = 8451125248 (8059MB) avail mem = 8190865408 (7811MB) mpath0 at root scsibus0 at mpath0: 256 targets mainbus0 at root bios0 at mainbus0: SMBIOS rev. 2.6 @ 0xdae9c000 (64 entries) bios0: vendor LENOVO version "8DET69WW (1.39 )" date 07/18/2013 bios0: LENOVO 4291G36 acpi0 at bios0: rev 2 acpi0: sleep states S0 S3 S4 S5 acpi0: tables DSDT FACP SLIC SSDT SSDT SSDT HPET APIC MCFG ECDT ASF! TCPA SSDT SSDT DMAR UEFI UEFI UEFI acpi0: wakeup devices LID_(S3) SLPB(S3) IGBE(S4) EXP4(S4) EXP7(S4) EHC1(S3) EHC2(S3) HDEF(S4) acpitimer0 at acpi0: 3579545 Hz, 24 bits acpihpet0 at acpi0: 14318179 Hz acpimadt0 at acpi0 addr 0xfee0: PC-AT compat cpu0 at mainbus0: apid 0 (boot processor) cpu0: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz, 2492.23 MHz cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI \ ,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3 \ ,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,NXE,LONG,LAHF, \ PERF,ITSC,SENSOR,ARAT cpu0: 256KB 64b/line 8-way L2 cache cpu0: smt 0, core 0, package 0 mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges cpu0: apic clock running at 99MHz cpu0: mwait min=64, max=64, C-substates=0.2.1.1.2, IBE cpu1 at mainbus0: apid 1 (application processor) cpu1: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz, 2491.91 MHz cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI \ ,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3 \ ,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,NXE,LONG,LAHF, \ PERF,ITSC,SENSOR,ARAT cpu1: 256KB 64b/line 8-way L2 cache cpu1: smt 1, core 0, package 0 cpu2 at mainbus0: apid 2 (application processor) cpu2: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz, 2491.91 MHz cpu2: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI \ ,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3 \ ,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,NXE,LONG,LAHF, \ PERF,ITSC,SENSOR,ARAT cpu2: 256KB 64b/line 8-way L2 cache cpu2: smt 0, core 1, package 0 cpu3 at mainbus0: apid 3 (application processor) cpu3: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz, 2491.91 MHz cpu3: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI \ ,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3 \ ,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,NXE,LONG,LAHF, \ PERF,ITSC,SENSOR,ARAT cpu3: 256KB 64b/line 8-way L2 cache cpu3: smt 1, core 1, package 0 ioapic0 at mainbus0: apid 2 pa 0xfec0, version 20, 24 pins acpimcfg0 at acpi0 addr 0xf800, bus 0-63 acpiec0 at acpi0 acpiprt0 at acpi0: bus 0 (PCI0) acpiprt1 at acpi0: bus -1 (PEG_) acpiprt2 at acpi0: bus 2 (EXP1) acpiprt3 at acpi0: bus 3 (EXP2) acpiprt4 at acpi0: bus 5 (EXP4) acpiprt5 at acpi0: bus 13 (EXP5) acpiprt6 at acpi0: bus -1 (EXP7) acpicpu0 at acpi0: C3(350@104 io@0x415), C1(1000@1 halt), PSS acpicpu1 at acpi0: C3(350@104 io@0x415), C1(1000@1 halt), PSS acpicpu2 at acpi0: C3(350@104 io@0x415), C1(1000@1 halt), PSS acpicpu3 at acpi0: C3(350@104 io@0x415), C1(1000@1 halt), PSS acpipwrres0 at acpi0: PUBS, resource for EHC1, EHC2 acpitz0 at acpi0: critical temperature is 99 degC acpibtn0 at acpi0: LID_ acpibtn1 at acpi0: SLPB acpibat0 at acpi0: BAT0 model "42T4940" serial 4448 type LION oem "SANYO" acpibat1 at acpi0: BAT1 not present acpiac0 at acpi0: AC unit online acpithinkpad0 at acpi0 acpidock0 at acpi0: GDCK not docked (0) cpu0: Enhanced SpeedStep 2492 MHz: speeds: 2501, 2500, 2200, 2000, 1800, 1600, 1400, 1200, 1000, 800 MHz pci0 at mainbus0 bus 0 pchb0 at pci0 dev 0 function 0 "Intel Core 2G Host" rev 0x09 inteldrm0 at pci0 dev 2 function 0 "Intel HD Graphics 3000" rev 0x09 drm0 at inteldrm0 inteldrm0: msi inteldrm0: 1366x768 wsdisplay0 at inteldrm0 mux 1: console (std, vt100 emulation) wsdisplay0: screen 1-5 added (std, vt100 emulation) "Intel
merge in_ and in6_pcbbind(), introduce in(6)_pcbaddrisavail()
in_pcbbind and in6_pcbbind have a lot in common, the only meaningful differences are in the checks done to ensure a sockaddr is available. This diff splits theses checks in their own functions, and merge the remaining code in one single function. Aside from being easier to read, it also makes it very easy to check sockaddr availability without actually binding. Tested on my own laptop for the last ten days ; no regression observed with regress/sys/netinet/in_pcbbind. Ok ? Index: netinet/in_pcb.c === RCS file: /cvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.195 diff -u -p -r1.195 in_pcb.c --- netinet/in_pcb.c18 Dec 2015 22:25:16 - 1.195 +++ netinet/in_pcb.c23 Dec 2015 08:07:14 - @@ -284,91 +284,129 @@ int in_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p) { struct socket *so = inp->inp_socket; - struct inpcbtable *table = inp->inp_table; - struct sockaddr_in *sin; u_int16_t lport = 0; - int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); + int wild = 0; int error; -#ifdef INET6 - if (sotopf(so) == PF_INET6) - return in6_pcbbind(inp, nam, p); -#endif /* INET6 */ - - if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) + if (inp->inp_lport != 0) return (EINVAL); + if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 && ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 || (so->so_options & SO_ACCEPTCONN) == 0)) wild = INPLOOKUP_WILDCARD; + if (nam) { - sin = mtod(nam, struct sockaddr_in *); - if (nam->m_len != sizeof(*sin)) + switch (sotopf(so)) { +#ifdef INET6 + case PF_INET6: { + struct sockaddr_in6 *sin6; + + if (TAILQ_EMPTY(_ifaddr)) + return (EADDRNOTAVAIL); + if (!IN6_IS_ADDR_UNSPECIFIED(>inp_laddr6)) + return (EINVAL); + + sin6 = mtod(nam, struct sockaddr_in6 *); + if (nam->m_len != sizeof(*sin6)) + return (EINVAL); + if (sin6->sin6_family != AF_INET6) + return (EAFNOSUPPORT); + if ((error = in6_pcbaddrisavail(inp, sin6, wild, p))) + return (error); + inp->inp_laddr6 = sin6->sin6_addr; + lport = sin6->sin6_port; + break; + } +#endif + case PF_INET: { + struct sockaddr_in *sin; + + if (inp->inp_laddr.s_addr != INADDR_ANY) + return (EINVAL); + + sin = mtod(nam, struct sockaddr_in *); + if (nam->m_len != sizeof(*sin)) + return (EINVAL); + if (sin->sin_family != AF_INET) + return (EAFNOSUPPORT); + if ((error = in_pcbaddrisavail(inp, sin, wild, p))) + return (error); + inp->inp_laddr = sin->sin_addr; + lport = sin->sin_port; + break; + } + default: return (EINVAL); + } + } + + if (lport == 0) + if ((error = in_pcbpickport(, wild, inp, p))) + return (error); + inp->inp_lport = lport; + in_pcbrehash(inp); + return (0); +} + +int +in_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in *sin, int wild, +struct proc *p) +{ + struct socket *so = inp->inp_socket; + struct inpcbtable *table = inp->inp_table; + u_int16_t lport = sin->sin_port; + int reuseport = (so->so_options & SO_REUSEPORT); + int error; - if (sin->sin_family != AF_INET) - return (EAFNOSUPPORT); + if (IN_MULTICAST(sin->sin_addr.s_addr)) { + /* +* Treat SO_REUSEADDR as SO_REUSEPORT for multicast; +* allow complete duplication of binding if +* SO_REUSEPORT is set, or if SO_REUSEADDR is set +* and a multicast address is bound on both +* new and duplicated sockets. +*/ + if (so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) + reuseport = SO_REUSEADDR|SO_REUSEPORT; + } else if (sin->sin_addr.s_addr != INADDR_ANY) { + + if ((so->so_options & SO_BINDANY) == 0 || + (so->so_type != SOCK_DGRAM) || + (sin->sin_addr.s_addr != INADDR_BROADCAST && +!in_broadcast(sin->sin_addr, inp->inp_rtableid))) { +