From nobody@FreeBSD.org  Tue Jan 28 11:15:41 2014
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115])
	(using TLSv1 with cipher ADH-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by hub.freebsd.org (Postfix) with ESMTPS id C8C18FE9
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 28 Jan 2014 11:15:41 +0000 (UTC)
Received: from oldred.freebsd.org (oldred.freebsd.org [IPv6:2001:1900:2254:206a::50:4])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by mx1.freebsd.org (Postfix) with ESMTPS id B4F8411B7
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 28 Jan 2014 11:15:41 +0000 (UTC)
Received: from oldred.freebsd.org ([127.0.1.6])
	by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id s0SBFfUM096896
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 28 Jan 2014 11:15:41 GMT
	(envelope-from nobody@oldred.freebsd.org)
Received: (from nobody@localhost)
	by oldred.freebsd.org (8.14.5/8.14.5/Submit) id s0SBFfFp096892;
	Tue, 28 Jan 2014 11:15:41 GMT
	(envelope-from nobody)
Message-Id: <201401281115.s0SBFfFp096892@oldred.freebsd.org>
Date: Tue, 28 Jan 2014 11:15:41 GMT
From: Fernando <fernando.apesteguia@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [linprocfs] [patch] emulate /proc/sys/kernel/random/uuid
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         186187
>Category:       kern
>Synopsis:       [linprocfs] [patch] emulate /proc/sys/kernel/random/uuid
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    eadler
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jan 28 11:20:00 UTC 2014
>Closed-Date:    
>Last-Modified:  Thu Mar 13 04:00:00 UTC 2014
>Originator:     Fernando
>Release:        9.1-RELEASE
>Organization:
>Environment:
>Description:
This patch implements /proc/sys/kernel/random/uuid for the linuxulator.

This is related to kern/183615 but the original submitter of the PR doesn't seem to be interested...
>How-To-Repeat:
Try to open that file under compat linux
>Fix:
Apply the attached patch.

Patch attached with submission follows:

--- compat/linprocfs/linprocfs.c.orig	2013-11-06 18:59:41.000000000 +0100
+++ compat/linprocfs/linprocfs.c	2013-11-06 23:56:22.000000000 +0100
@@ -72,6 +72,7 @@
 #include <sys/time.h>
 #include <sys/tty.h>
 #include <sys/user.h>
+#include <sys/uuid.h>
 #include <sys/vmmeter.h>
 #include <sys/vnode.h>
 #include <sys/bus.h>
@@ -1347,6 +1348,23 @@
 	return (0);
 }
 
+
+/*
+ * Filler function for proc/sys/kernel/random/uuid
+ */
+static int
+linprocfs_douuid(PFS_FILL_ARGS)
+{
+	struct uuid uuid;
+
+	kern_uuidgen(&uuid, 1);
+
+	sbuf_printf_uuid(sb, &uuid);
+	sbuf_printf(sb, "\n");
+
+	return(0);
+}
+
 /*
  * Constructor
  */
@@ -1445,6 +1463,8 @@
 	    NULL, NULL, NULL, PFS_RD);
 	pfs_create_file(dir, "sem", &linprocfs_dosem,
 	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(dir, "random", &linprocfs_douuid,
+	    NULL, NULL, NULL, PFS_RD);
 
 	return (0);
 }


>Release-Note:
>Audit-Trail:

From: Mateusz Guzik <mjguzik@gmail.com>
To: bug-followup@FreeBSD.org, fernando.apesteguia@gmail.com
Cc:  
Subject: Re: kern/186187: [linprocfs] [patch] emulate
 /proc/sys/kernel/random/uuid
Date: Tue, 28 Jan 2014 20:52:35 +0100

 This patch seems to provide uuid in a file 'random' instead of 'uuid' in
 a 'random' directory.
 
 In addition to that there are some whitespace issues.
 
 -- 
 Mateusz Guzik <mjguzik gmail.com>

From: =?ISO-8859-1?Q?Fernando_Apestegu=EDa?= <fernando.apesteguia@gmail.com>
To: bug-followup@FreeBSD.org, fernando.apesteguia@gmail.com
Cc:  
Subject: Re: kern/186187: [linprocfs] [patch] emulate /proc/sys/kernel/random/uuid
Date: Tue, 28 Jan 2014 23:15:01 +0100

 --001a11c24bfad3a73e04f10f271a
 Content-Type: multipart/alternative; boundary=001a11c24bfad3a72f04f10f2718
 
 --001a11c24bfad3a72f04f10f2718
 Content-Type: text/plain; charset=ISO-8859-1
 
 Sorry for the sloppy patch.
 
 This should fix those issues.
 
 Cheers.
 
 --001a11c24bfad3a72f04f10f2718
 Content-Type: text/html; charset=ISO-8859-1
 
 <div dir="ltr"><div>Sorry for the sloppy patch.<br><br>This should fix those issues.<br><br></div>Cheers.<br></div>
 
 --001a11c24bfad3a72f04f10f2718--
 --001a11c24bfad3a73e04f10f271a
 Content-Type: text/x-patch; charset=US-ASCII; name="linprocfs-random-uuid.patch"
 Content-Disposition: attachment; filename="linprocfs-random-uuid.patch"
 Content-Transfer-Encoding: base64
 X-Attachment-Id: f_hqzq28jz0
 
 LS0tIGxpbnByb2Nmcy5jLm9yaWcJMjAxMy0xMS0wNiAxODo1OTo0MS4wMDAwMDAwMDAgKzAxMDAK
 KysrIGxpbnByb2Nmcy5jCTIwMTQtMDEtMjggMjM6MDk6NDYuMDAwMDAwMDAwICswMTAwCkBAIC03
 Miw2ICs3Miw3IEBACiAjaW5jbHVkZSA8c3lzL3RpbWUuaD4KICNpbmNsdWRlIDxzeXMvdHR5Lmg+
 CiAjaW5jbHVkZSA8c3lzL3VzZXIuaD4KKyNpbmNsdWRlIDxzeXMvdXVpZC5oPgogI2luY2x1ZGUg
 PHN5cy92bW1ldGVyLmg+CiAjaW5jbHVkZSA8c3lzL3Zub2RlLmg+CiAjaW5jbHVkZSA8c3lzL2J1
 cy5oPgpAQCAtMTM0Nyw2ICsxMzQ4LDIzIEBACiAJcmV0dXJuICgwKTsKIH0KIAorCisvKgorICog
 RmlsbGVyIGZ1bmN0aW9uIGZvciBwcm9jL3N5cy9rZXJuZWwvcmFuZG9tL3V1aWQKKyAqLworc3Rh
 dGljIGludAorbGlucHJvY2ZzX2RvdXVpZChQRlNfRklMTF9BUkdTKQoreworCXN0cnVjdCB1dWlk
 IHV1aWQ7CisKKwlrZXJuX3V1aWRnZW4oJnV1aWQsIDEpOworCisJc2J1Zl9wcmludGZfdXVpZChz
 YiwgJnV1aWQpOworCXNidWZfcHJpbnRmKHNiLCAiXG4iKTsKKworCXJldHVybigwKTsKK30KKwog
 LyoKICAqIENvbnN0cnVjdG9yCiAgKi8KQEAgLTE0NDYsNiArMTQ2NCwxMSBAQAogCXBmc19jcmVh
 dGVfZmlsZShkaXIsICJzZW0iLCAmbGlucHJvY2ZzX2Rvc2VtLAogCSAgICBOVUxMLCBOVUxMLCBO
 VUxMLCBQRlNfUkQpOwogCisJLyogL3Byb2Mvc3lzL2tlcm5lbC9yYW5kb20vLi4uICovCisJZGly
 ID0gcGZzX2NyZWF0ZV9kaXIoZGlyLCAicmFuZG9tIiwgTlVMTCwgTlVMTCwgTlVMTCwgMCk7CisJ
 cGZzX2NyZWF0ZV9maWxlKGRpciwgInV1aWQiLCAmbGlucHJvY2ZzX2RvdXVpZCwKKwkgICAgTlVM
 TCwgTlVMTCwgTlVMTCwgUEZTX1JEKTsKKwogCXJldHVybiAoMCk7CiB9CiAK
 --001a11c24bfad3a73e04f10f271a--
Responsible-Changed-From-To: freebsd-bugs->eadler 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Tue Feb 18 03:15:54 UTC 2014 
Responsible-Changed-Why:  
I'll take it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=186187 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/186187: commit references a PR
Date: Thu, 27 Feb 2014 00:43:18 +0000 (UTC)

 Author: eadler
 Date: Thu Feb 27 00:43:10 2014
 New Revision: 262539
 URL: http://svnweb.freebsd.org/changeset/base/262539
 
 Log:
   linprocfs: add support for /sys/kernel/random/uuid
   
   PR:		kern/186187
   Submitted by:	Fernando <fernando.apesteguia@gmail.com>
   MFC After:	2 weeks
 
 Modified:
   head/sys/compat/linprocfs/linprocfs.c
   head/usr.bin/makewhatis/makewhatis.1
   head/usr.bin/makewhatis/makewhatis.c
 
 Modified: head/sys/compat/linprocfs/linprocfs.c
 ==============================================================================
 --- head/sys/compat/linprocfs/linprocfs.c	Wed Feb 26 23:03:10 2014	(r262538)
 +++ head/sys/compat/linprocfs/linprocfs.c	Thu Feb 27 00:43:10 2014	(r262539)
 @@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/time.h>
  #include <sys/tty.h>
  #include <sys/user.h>
 +#include <sys/uuid.h>
  #include <sys/vmmeter.h>
  #include <sys/vnode.h>
  #include <sys/bus.h>
 @@ -1337,6 +1338,22 @@ linprocfs_dofdescfs(PFS_FILL_ARGS)
  	return (0);
  }
  
 +
 +/*
 + * Filler function for proc/sys/kernel/random/uuid
 + */
 +static int
 +linprocfs_douuid(PFS_FILL_ARGS)
 +{
 +	struct uuid uuid;
 +
 +	kern_uuidgen(&uuid, 1);
 +	sbuf_printf_uuid(sb, &uuid);
 +	sbuf_printf(sb, "\n");
 +	return(0);
 +}
 +
 +
  /*
   * Constructor
   */
 @@ -1436,6 +1453,11 @@ linprocfs_init(PFS_INIT_ARGS)
  	pfs_create_file(dir, "sem", &linprocfs_dosem,
  	    NULL, NULL, NULL, PFS_RD);
  
 +	/* /proc/sys/kernel/random/... */
 +	dir = pfs_create_dir(dir, "random", NULL, NULL, NULL, 0);
 +	pfs_create_file(dir, "uuid", &linprocfs_douuid,
 +	    NULL, NULL, NULL, PFS_RD);
 +
  	return (0);
  }
  
 
 Modified: head/usr.bin/makewhatis/makewhatis.1
 ==============================================================================
 --- head/usr.bin/makewhatis/makewhatis.1	Wed Feb 26 23:03:10 2014	(r262538)
 +++ head/usr.bin/makewhatis/makewhatis.1	Thu Feb 27 00:43:10 2014	(r262539)
 @@ -24,12 +24,12 @@
  .\"
  .\" $FreeBSD$
  .\"
 -.Dd December 3, 2005
 -.Dt MAKEWHATIS 1
 +.Dd December 8, 2013
 +.Dt MAKEWHATIS 8
  .Os
  .Sh NAME
  .Nm makewhatis
 -.Nd "create whatis database"
 +.Nd create whatis database
  .Sh SYNOPSIS
  .Nm
  .Op Fl a
 @@ -98,9 +98,6 @@ option is used.
  .It Ev MACHINE
  If set, its value is used to override the current
  machine type when searching machine specific subdirectories.
 -.It Ev MACHINE_ARCH
 -If set, its value is used to override the current
 -architecture when searching architecture specific subdirectories.
  .It Ev MANPATH
  Determines the set of directories to be processed if none are given on
  the command line.
 @@ -133,4 +130,6 @@ program was originally written in Perl a
  The current version of
  .Nm
  was rewritten in C by
 -.An John Rochester .
 +.An John Rochester
 +with additional contributions by
 +.An Franco Fichtner Aq Mt franco@lastsummer.de .
 
 Modified: head/usr.bin/makewhatis/makewhatis.c
 ==============================================================================
 --- head/usr.bin/makewhatis/makewhatis.c	Wed Feb 26 23:03:10 2014	(r262538)
 +++ head/usr.bin/makewhatis/makewhatis.c	Thu Feb 27 00:43:10 2014	(r262539)
 @@ -1,5 +1,6 @@
  /*-
   * Copyright (c) 2002 John Rochester
 + * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
 @@ -24,21 +25,19 @@
   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + *
 + * $FreeBSD$
   */
  
 -#include <sys/cdefs.h>
 -__FBSDID("$FreeBSD$");
 -
 +#include <sys/tree.h>
  #include <sys/types.h>
 -#include <sys/stat.h>
  #include <sys/param.h>
  #include <sys/queue.h>
 -#include <sys/utsname.h>
 +#include <sys/stat.h>
  
  #include <ctype.h>
  #include <dirent.h>
  #include <err.h>
 -#include <stddef.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
 @@ -52,16 +51,56 @@ __FBSDID("$FreeBSD$");
  static char blank[] = 		"";
  
  /*
 - * Information collected about each man page in a section.
 + * Information collected about each man page alias.
 + */
 +struct page_alias {
 +	RB_ENTRY(page_alias) entry;
 +	char *filename;
 +	char *name;
 +	char *suffix;
 +	int gzipped;
 +};
 +
 +/*
 + * Information collected about each unique man page.
   */
  struct page_info {
 -	char *	filename;
 -	char *	name;
 -	char *	suffix;
 -	int	gzipped;
 -	ino_t	inode;
 +	RB_HEAD(page_alias_tree, page_alias) head;
 +	RB_ENTRY(page_info) entry;
 +	ino_t inode;
  };
  
 +static RB_HEAD(page_info_tree, page_info) page_head = RB_INITIALIZER(&page_head);
 +
 +/*
 + * Sorts page info by inode number.
 + */
 +static int
 +infosort(const struct page_info *a, const struct page_info *b)
 +{
 +	return (memcmp(&a->inode, &b->inode, sizeof(a->inode)));
 +}
 +
 +RB_PROTOTYPE(page_info_tree, page_info, entry, infosort);
 +RB_GENERATE(page_info_tree, page_info, entry, infosort);
 +
 +/*
 + * Sorts page alias first by suffix, then name.
 + */
 +static int
 +aliassort(const struct page_alias *a, const struct page_alias *b)
 +{
 +	int ret = strcmp(a->suffix, b->suffix);
 +	if (ret) {
 +		return (ret);
 +	}
 +
 +	return (strcmp(a->name, b->name));
 +}
 +
 +RB_PROTOTYPE(page_alias_tree, page_alias, entry, aliassort);
 +RB_GENERATE(page_alias_tree, page_alias, entry, aliassort);
 +
  /*
   * An entry kept for each visited directory.
   */
 @@ -100,7 +139,7 @@ static const char *whatis_name="whatis";
  static char *common_output;		/* -o option: the single output file */
  static char *locale;			/* user's locale if -L is used */
  static char *lang_locale;		/* short form of locale */
 -static const char *machine, *machine_arch;
 +static const char *machine;
  
  static int exit_code;			/* exit code to use when finished */
  static SLIST_HEAD(, visited_dir) visited_dirs =
 @@ -132,62 +171,66 @@ static char mdoc_commands[] = "ArDvErEvF
  static void
  free_page_info(struct page_info *info)
  {
 -	free(info->filename);
 -	free(info->name);
 -	free(info->suffix);
 +	struct page_alias *alias;
 +
 +	while ((alias = RB_ROOT(&info->head))) {
 +		RB_REMOVE(page_alias_tree, &info->head, alias);
 +		free(alias->filename);
 +		free(alias->suffix);
 +		free(alias->name);
 +		free(alias);
 +	}
 +
  	free(info);
  }
  
  /*
 - * Allocates and fills in a new struct page_info given the
 - * name of the man section directory and the dirent of the file.
 - * If the file is not a man page, returns NULL.
 + * Allocates and fills in a new struct page_alias given the
 + * full file name of the man page and its dirent.
 + * If the file is not a man page, nothing is added.
   */
 -static struct page_info *
 -new_page_info(char *dir, struct dirent *dirent)
 +static void
 +new_page_alias(struct page_info *info, char *filename, struct dirent *dirent)
  {
 -	struct page_info *info;
 -	int basename_length;
 +	int gzipped, basename_length;
 +	struct page_alias *alias;
  	char *suffix;
 -	struct stat st;
  
 -	info = (struct page_info *) malloc(sizeof(struct page_info));
 -	if (info == NULL)
 -		err(1, "malloc");
  	basename_length = strlen(dirent->d_name);
  	suffix = &dirent->d_name[basename_length];
 -	asprintf(&info->filename, "%s/%s", dir, dirent->d_name);
 -	if ((info->gzipped = basename_length >= 4 && strcmp(&dirent->d_name[basename_length - 3], ".gz") == 0)) {
 +
 +	gzipped = basename_length >= 4 &&
 +	    strcmp(&dirent->d_name[basename_length - 3], ".gz") == 0;
 +	if (gzipped) {
  		suffix -= 3;
  		*suffix = '\0';
  	}
 +
  	for (;;) {
  		if (--suffix == dirent->d_name || !isalnum(*suffix)) {
 -			if (*suffix == '.')
 +			if (*suffix == '.') {
  				break;
 -			if (verbose)
 -				warnx("%s: invalid man page name", info->filename);
 -			free(info->filename);
 -			free(info);
 -			return NULL;
 +			}
 +			if (verbose) {
 +				warnx("%s: invalid man page name", filename);
 +			}
 +			return;
  		}
  	}
 +
  	*suffix++ = '\0';
 -	info->name = strdup(dirent->d_name);
 -	info->suffix = strdup(suffix);
 -	if (stat(info->filename, &st) < 0) {
 -		warn("%s", info->filename);
 -		free_page_info(info);
 -		return NULL;
 -	}
 -	if (!S_ISREG(st.st_mode)) {
 -		if (verbose && !S_ISDIR(st.st_mode))
 -			warnx("%s: not a regular file", info->filename);
 -		free_page_info(info);
 -		return NULL;
 +
 +	alias = malloc(sizeof(*alias));
 +	if (alias == NULL) {
 +		err(1, "malloc");
  	}
 -	info->inode = st.st_ino;
 -	return info;
 +
 +	alias->name = strdup(dirent->d_name);	/* XXX unsafe */
 +	alias->filename = strdup(filename);	/* XXX unsafe */
 +	alias->suffix = strdup(suffix);		/* XXX unsafe */
 +	alias->gzipped = gzipped;
 +
 +	RB_INSERT(page_alias_tree, &info->head, alias);
  }
  
  /*
 @@ -206,10 +249,10 @@ static struct sbuf *
  new_sbuf(void)
  {
  	struct sbuf *sbuf = (struct sbuf *) malloc(sizeof(struct sbuf));
 -	sbuf->content = (char *) malloc(LINE_ALLOC);
 +	sbuf->content = malloc(LINE_ALLOC);
  	sbuf->last = sbuf->content + LINE_ALLOC - 1;
  	sbuf_clear(sbuf);
 -	return sbuf;
 +	return(sbuf);
  }
  
  /*
 @@ -227,7 +270,7 @@ sbuf_need(struct sbuf *sbuf, int nchars)
  		size *= 2;
  		cntsize = sbuf->end - sbuf->content;
  
 -		new_content = (char *)malloc(size);
 +		new_content = malloc(size);
  		memcpy(new_content, sbuf->content, cntsize);
  		free(sbuf->content);
  		sbuf->content = new_content;
 @@ -288,29 +331,7 @@ static char *
  sbuf_content(struct sbuf *sbuf)
  {
  	*sbuf->end = '\0';
 -	return sbuf->content;
 -}
 -
 -/*
 - * Returns true if no man page exists in the directory with
 - * any of the names in the StringList.
 - */
 -static int
 -no_page_exists(char *dir, StringList *names, char *suffix)
 -{
 -	char path[MAXPATHLEN];
 -	size_t i;
 -
 -	for (i = 0; i < names->sl_cur; i++) {
 -		snprintf(path, sizeof path, "%s/%s.%s.gz", dir, names->sl_str[i], suffix);
 -		if (access(path, F_OK) < 0) {
 -			path[strlen(path) - 3] = '\0';
 -			if (access(path, F_OK) < 0)
 -				continue;
 -		}
 -		return 0;
 -	}
 -	return 1;
 +	return(sbuf->content);
  }
  
  static void
 @@ -337,7 +358,7 @@ open_output(char *name)
  		if (output == NULL) {
  			warn("%s", name);
  			exit_code = 1;
 -			return NULL;
 +			return(NULL);
  		}
  		while (fgets(line, sizeof line, output) != NULL) {
  			line[strlen(line) - 1] = '\0';
 @@ -352,15 +373,15 @@ open_output(char *name)
  	if (output == NULL) {
  		warn("%s", name);
  		exit_code = 1;
 -		return NULL;
 +		return(NULL);
  	}
 -	return output;
 +	return(output);
  }
  
  static int
  linesort(const void *a, const void *b)
  {
 -	return strcmp((*(const char * const *)a), (*(const char * const *)b));
 +	return(strcmp((*(const char * const *)a), (*(const char * const *)b)));
  }
  
  /*
 @@ -372,7 +393,8 @@ finish_output(FILE *output, char *name)
  	size_t i;
  	char *prev = NULL;
  
 -	qsort(whatis_lines->sl_str, whatis_lines->sl_cur, sizeof(char *), linesort);
 +	qsort(whatis_lines->sl_str, whatis_lines->sl_cur, sizeof(char *),
 +	      linesort);
  	for (i = 0; i < whatis_lines->sl_cur; i++) {
  		char *line = whatis_lines->sl_str[i];
  		if (i > 0 && strcmp(line, prev) == 0)
 @@ -395,7 +417,7 @@ open_whatis(char *mandir)
  	char filename[MAXPATHLEN];
  
  	snprintf(filename, sizeof filename, "%s/%s", mandir, whatis_name);
 -	return open_output(filename);
 +	return(open_output(filename));
  }
  
  static void
 @@ -419,20 +441,20 @@ already_visited(char *dir)
  	if (stat(dir, &st) < 0) {
  		warn("%s", dir);
  		exit_code = 1;
 -		return 1;
 +		return(1);
  	}
  	SLIST_FOREACH(visit, &visited_dirs, next) {
  		if (visit->inode == st.st_ino &&
  		    visit->device == st.st_dev) {
  			warnx("already visited %s", dir);
 -			return 1;
 +			return(1);
  		}
  	}
  	visit = (struct visited_dir *) malloc(sizeof(struct visited_dir));
  	visit->device = st.st_dev;
  	visit->inode = st.st_ino;
  	SLIST_INSERT_HEAD(&visited_dirs, visit, next);
 -	return 0;
 +	return(0);
  }
  
  /*
 @@ -446,7 +468,7 @@ trim_rhs(char *str)
  	while (--rhs > str && isspace(*rhs))
  		;
  	*++rhs = '\0';
 -	return rhs;
 +	return(rhs);
  }
  
  /*
 @@ -457,7 +479,7 @@ skip_spaces(char *s)
  {
  	while (*s != '\0' && isspace(*s))
  		s++;
 -	return s;
 +	return(s);
  }
  
  /*
 @@ -467,10 +489,10 @@ static int
  only_digits(char *line)
  {
  	if (!isdigit(*line++))
 -		return 0;
 +		return(0);
  	while (isdigit(*line))
  		line++;
 -	return *line == '\0';
 +	return(*line == '\0');
  }
  
  /*
 @@ -487,7 +509,7 @@ name_section_line(char *line, const char
  	const char **title;
  
  	if (strncmp(line, section_start, 3) != 0)
 -		return 0;
 +		return(0);
  	line = skip_spaces(line + 3);
  	rhs = trim_rhs(line);
  	if (*line == '"') {
 @@ -497,8 +519,8 @@ name_section_line(char *line, const char
  	}
  	for (title = name_section_titles; *title != NULL; title++)
  		if (strcmp(*title, line) == 0)
 -			return 1;
 -	return 0;
 +			return(1);
 +	return(0);
  }
  
  /*
 @@ -518,7 +540,7 @@ de_nroff_copy(char *from, char *to, int 
  			switch (*++from) {
  			case '(':
  				if (strncmp(&from[1], "em", 2) == 0 ||
 -						strncmp(&from[1], "mi", 2) == 0) {
 +				    strncmp(&from[1], "mi", 2) == 0) {
  					from += 3;
  					continue;
  				}
 @@ -534,7 +556,8 @@ de_nroff_copy(char *from, char *to, int 
  				if (*++from == '(')
  					from += 3;
  				else if (*from == '[') {
 -					while (*++from != ']' && from < from_end);
 +					while (*++from != ']' && from < from_end)
 +						;
  					from++;
  				} else
  					from++;
 @@ -547,7 +570,7 @@ de_nroff_copy(char *from, char *to, int 
  		}
  		*to++ = *from++;
  	}
 -	return to;
 +	return(to);
  }
  
  /*
 @@ -594,6 +617,38 @@ process_man_line(char *line)
  	}
  }
  
 +struct mdoc_text {
 +	const char *mdoc;
 +	const char *text;
 +};
 +
 +static int
 +process_mdoc_macro(char *line)
 +{
 +	static const struct mdoc_text list[] = {
 +		{ ".At", "AT&T UNIX" },
 +		{ ".Bsx", "BSD/OS" },
 +		{ ".Bx", "BSD" },
 +		{ ".Dx", "DragonFly" },
 +		{ ".Fx", "FreeBSD" },
 +		{ ".Nx", "NetBSD" },
 +		{ ".Ox", "OpenBSD" },
 +		{ ".Ux", "UNIX" },
 +	};
 +	unsigned int i;
 +
 +	for (i = 0; i < sizeof(list) / sizeof(list[0]); ++i) {
 +		if (!strcmp(line, list[i].mdoc)) {
 +			sbuf_append(whatis_proto, list[i].text,
 +			    strlen(list[i].text));
 +			sbuf_append(whatis_proto, " ", 1);
 +			return (1);
 +		}
 +	}
 +
 +	return (0);
 +}
 +
  /*
   * Processes a new-style mdoc(7) line.
   */
 @@ -613,6 +668,9 @@ process_mdoc_line(char *line)
  		sbuf_append(whatis_proto, " ", 1);
  		return;
  	}
 +	if (process_mdoc_macro(line)) {
 +		return;
 +	}
  	xref = strncmp(line, ".Xr", 3) == 0;
  	line += 3;
  	while ((line = skip_spaces(line)) < line_end) {
 @@ -663,27 +721,6 @@ process_mdoc_line(char *line)
  		sbuf_append(whatis_proto, " ", 1);
  }
  
 -/*
 - * Collects a list of comma-separated names from the text.
 - */
 -static void
 -collect_names(StringList *names, char *text)
 -{
 -	char *arg;
 -
 -	for (;;) {
 -		arg = text;
 -		text = strchr(text, ',');
 -		if (text != NULL)
 -			*text++ = '\0';
 -		sl_add(names, arg);
 -		if (text == NULL)
 -			return;
 -		if (*text == ' ')
 -			text++;
 -	}
 -}
 -
  enum { STATE_UNKNOWN, STATE_MANSTYLE, STATE_MDOCNAME, STATE_MDOCDESC };
  
  /*
 @@ -691,25 +728,33 @@ enum { STATE_UNKNOWN, STATE_MANSTYLE, ST
   * to whatis_lines.
   */
  static void
 -process_page(struct page_info *page, char *section_dir)
 +process_page(struct page_info *info)
  {
 -	gzFile in;
 -	char buffer[4096];
 -	char *line;
 -	StringList *names;
 -	char *descr;
  	int state = STATE_UNKNOWN;
 -	size_t i;
 +	struct page_alias *alias;
 +	char *line, *descr;
 +	char buffer[4096];
 +	gzFile in;
 +
 +	/*
 +	 * Only read the page once for each inode.  It's
 +	 * safe to assume that page->list is set.
 +	 */
 +	alias = RB_MIN(page_alias_tree, &info->head);
 +
 +	if (verbose) {
 +		fprintf(stderr, "\treading %s\n", alias->filename);
 +	}
  
  	sbuf_clear(whatis_proto);
 -	if ((in = gzopen(page->filename, "r")) == NULL) {
 -		warn("%s", page->filename);
 +	if ((in = gzopen(alias->filename, "r")) == NULL) {
 +		warn("%s", alias->filename);
  		exit_code = 1;
  		return;
  	}
 -	while (gzgets(in, buffer, sizeof buffer) != NULL) {
 +	while (gzgets(in, buffer, sizeof(buffer)) != NULL) {
  		line = buffer;
 -		if (strncmp(line, ".\\\"", 3) == 0)		/* ignore comments */
 +		if (strncmp(line, ".\\\"", 3) == 0)	/* ignore comments */
  			continue;
  		switch (state) {
  		/*
 @@ -779,7 +824,9 @@ process_page(struct page_info *page, cha
  		descr = strchr(line, ' ');
  		if (descr == NULL) {
  			if (verbose)
 -				fprintf(stderr, "	ignoring junk description \"%s\"\n", line);
 +				fprintf(stderr,
 +					"\tignoring junk description \"%s\"\n",
 +					line);
  			return;
  		}
  		*descr++ = '\0';
 @@ -787,19 +834,16 @@ process_page(struct page_info *page, cha
  		*descr = '\0';
  		descr += 3;
  	}
 -	names = sl_init();
 -	collect_names(names, line);
  	sbuf_clear(whatis_final);
 -	if (!sl_find(names, page->name) && no_page_exists(section_dir, names, page->suffix)) {
 +	RB_FOREACH(alias, page_alias_tree, &info->head) {
  		/*
 -		 * Add the page name since that's the only thing that
 -		 * man(1) will find.
 +		 * This won't append names stored in `line'.
 +		 * The reason for that is that we cannot be sure
 +		 * which section they belong to unless we have
 +		 * a real alias (via MLINKS) in this list.
  		 */
 -		add_whatis_name(page->name, page->suffix);
 +		add_whatis_name(alias->name, alias->suffix);
  	}
 -	for (i = 0; i < names->sl_cur; i++)
 -		add_whatis_name(names->sl_str[i], page->suffix);
 -	sl_free(names, 0);
  	sbuf_retract(whatis_final, 2);		/* remove last ", " */
  	while (sbuf_length(whatis_final) < indent)
  		sbuf_append(whatis_final, " ", 1);
 @@ -809,33 +853,19 @@ process_page(struct page_info *page, cha
  }
  
  /*
 - * Sorts pages first by inode number, then by name.
 - */
 -static int
 -pagesort(const void *a, const void *b)
 -{
 -	const struct page_info *p1 = *(struct page_info * const *) a;
 -	const struct page_info *p2 = *(struct page_info * const *) b;
 -	if (p1->inode == p2->inode)
 -		return strcmp(p1->name, p2->name);
 -	return p1->inode - p2->inode;
 -}
 -
 -/*
   * Processes a single man section.
   */
  static void
  process_section(char *section_dir)
  {
  	struct dirent **entries;
 +	struct page_info *info;
  	int nentries;
 -	struct page_info **pages;
 -	int npages = 0;
  	int i;
 -	ino_t prev_inode = 0;
  
 -	if (verbose)
 +	if (verbose) {
  		fprintf(stderr, "  %s\n", section_dir);
 +	}
  
  	/*
  	 * scan the man section directory for pages
 @@ -846,33 +876,55 @@ process_section(char *section_dir)
  		exit_code = 1;
  		return;
  	}
 +
  	/*
  	 * collect information about man pages
  	 */
 -	pages = (struct page_info **) calloc(nentries, sizeof(struct page_info *));
  	for (i = 0; i < nentries; i++) {
 -		struct page_info *info = new_page_info(section_dir, entries[i]);
 -		if (info != NULL)
 -			pages[npages++] = info;
 +		struct page_info ref;
 +		char *filename;
 +		struct stat st;
 +
 +		if (asprintf(&filename, "%s/%s", section_dir,
 +		    entries[i]->d_name) < 0) {
 +			err(1, "malloc");
 +		}
 +
 +		if (stat(filename, &st) < 0) {
 +			warn("%s", filename);
 +			goto process_section_next;
 +		}
 +
 +		if (!S_ISREG(st.st_mode)) {
 +			if (verbose && !S_ISDIR(st.st_mode))
 +			    warnx("%s: not a regular file", filename);
 +			goto process_section_next;
 +		}
 +
 +		ref.inode = st.st_ino;
 +
 +		info = RB_FIND(page_info_tree, &page_head, &ref);
 +		if (info == NULL) {
 +			info = malloc(sizeof(*info));
 +			if (info == NULL) {
 +				err(1, "malloc");
 +			}
 +
 +			bzero(info, sizeof(*info));
 +			info->inode = st.st_ino;
 +			RB_INIT(&info->head);
 +
 +			RB_INSERT(page_info_tree, &page_head, info);
 +		}
 +
 +		new_page_alias(info, filename, entries[i]);
 +
 +process_section_next:
 +
  		free(entries[i]);
 +		free(filename);
  	}
  	free(entries);
 -	qsort(pages, npages, sizeof(struct page_info *), pagesort);
 -	/*
 -	 * process each unique page
 -	 */
 -	for (i = 0; i < npages; i++) {
 -		struct page_info *page = pages[i];
 -		if (page->inode != prev_inode) {
 -			prev_inode = page->inode;
 -			if (verbose)
 -				fprintf(stderr, "	reading %s\n", page->filename);
 -			process_page(page, section_dir);
 -		} else if (verbose)
 -			fprintf(stderr, "	skipping %s, duplicate\n", page->filename);
 -		free_page_info(page);
 -	}
 -	free(pages);
  }
  
  /*
 @@ -884,12 +936,12 @@ select_sections(const struct dirent *ent
  	const char *p = &entry->d_name[3];
  
  	if (strncmp(entry->d_name, "man", 3) != 0)
 -		return 0;
 +		return(0);
  	while (*p != '\0') {
  		if (!isalnum(*p++))
 -			return 0;
 +			return(0);
  	}
 -	return 1;
 +	return(1);
  }
  
  /*
 @@ -900,6 +952,7 @@ static void
  process_mandir(char *dir_name)
  {
  	struct dirent **entries;
 +	struct page_info *info;
  	int nsections;
  	FILE *fp = NULL;
  	int i;
 @@ -919,21 +972,26 @@ process_mandir(char *dir_name)
  		return;
  	for (i = 0; i < nsections; i++) {
  		char section_dir[MAXPATHLEN];
 -		snprintf(section_dir, sizeof section_dir, "%s/%s", dir_name, entries[i]->d_name);
 +		snprintf(section_dir, sizeof section_dir, "%s/%s", dir_name,
 +			 entries[i]->d_name);
  		process_section(section_dir);
  		snprintf(section_dir, sizeof section_dir, "%s/%s/%s", dir_name,
 -		    entries[i]->d_name, machine);
 +			 entries[i]->d_name, machine);
  		if (stat(section_dir, &st) == 0 && S_ISDIR(st.st_mode))
  			process_section(section_dir);
 -		if (strcmp(machine_arch, machine) != 0) {
 -			snprintf(section_dir, sizeof section_dir, "%s/%s/%s",
 -			    dir_name, entries[i]->d_name, machine_arch);
 -			if (stat(section_dir, &st) == 0 && S_ISDIR(st.st_mode))
 -				process_section(section_dir);
 -		}
  		free(entries[i]);
  	}
  	free(entries);
 +
 +	/*
 +	 * process and free all pages
 +	 */
 +	while ((info = RB_ROOT(&page_head))) {
 +		RB_REMOVE(page_info_tree, &page_head, info);
 +		process_page(info);
 +		free_page_info(info);
 +	}
 +
  	if (common_output == NULL)
  		finish_whatis(fp, dir_name);
  }
 @@ -1003,7 +1061,9 @@ main(int argc, char **argv)
  				char *sep = strchr(locale, '_');
  				if (sep != NULL && isupper(sep[1]) &&
  				    isupper(sep[2])) {
 -					asprintf(&lang_locale, "%.*s%s", (int)(ptrdiff_t)(sep - locale), locale, &sep[3]);
 +					asprintf(&lang_locale, "%.*s%s",
 +					    (int)(sep - locale),
 +					    locale, &sep[3]);
  				}
  			}
  			break;
 @@ -1021,16 +1081,8 @@ main(int argc, char **argv)
  	whatis_proto = new_sbuf();
  	whatis_final = new_sbuf();
  
 -	if ((machine = getenv("MACHINE")) == NULL) {
 -		static struct utsname utsname;
 -
 -		if (uname(&utsname) == -1)
 -			err(1, "uname");
 -		machine = utsname.machine;
 -	}
 -
 -	if ((machine_arch = getenv("MACHINE_ARCH")) == NULL)
 -		machine_arch = MACHINE_ARCH;
 +	if ((machine = getenv("MACHINE")) == NULL)
 +		machine = MACHINE;
  
  	if (common_output != NULL && (fp = open_output(common_output)) == NULL)
  		err(1, "%s", common_output);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/186187: commit references a PR
Date: Thu, 13 Mar 2014 03:42:15 +0000 (UTC)

 Author: eadler
 Date: Thu Mar 13 03:42:00 2014
 New Revision: 263101
 URL: http://svnweb.freebsd.org/changeset/base/263101
 
 Log:
   MFC r262539:
   linprocfs: add support for /sys/kernel/random/uuid
   
   PR:		kern/186187
 
 Modified:
   stable/10/sys/compat/linprocfs/linprocfs.c
   stable/10/usr.bin/makewhatis/makewhatis.1
   stable/10/usr.bin/makewhatis/makewhatis.c
 Directory Properties:
   stable/10/   (props changed)
 
 Modified: stable/10/sys/compat/linprocfs/linprocfs.c
 ==============================================================================
 --- stable/10/sys/compat/linprocfs/linprocfs.c	Thu Mar 13 01:16:51 2014	(r263100)
 +++ stable/10/sys/compat/linprocfs/linprocfs.c	Thu Mar 13 03:42:00 2014	(r263101)
 @@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/time.h>
  #include <sys/tty.h>
  #include <sys/user.h>
 +#include <sys/uuid.h>
  #include <sys/vmmeter.h>
  #include <sys/vnode.h>
  #include <sys/bus.h>
 @@ -1336,6 +1337,22 @@ linprocfs_dofdescfs(PFS_FILL_ARGS)
  	return (0);
  }
  
 +
 +/*
 + * Filler function for proc/sys/kernel/random/uuid
 + */
 +static int
 +linprocfs_douuid(PFS_FILL_ARGS)
 +{
 +	struct uuid uuid;
 +
 +	kern_uuidgen(&uuid, 1);
 +	sbuf_printf_uuid(sb, &uuid);
 +	sbuf_printf(sb, "\n");
 +	return(0);
 +}
 +
 +
  /*
   * Constructor
   */
 @@ -1435,6 +1452,11 @@ linprocfs_init(PFS_INIT_ARGS)
  	pfs_create_file(dir, "sem", &linprocfs_dosem,
  	    NULL, NULL, NULL, PFS_RD);
  
 +	/* /proc/sys/kernel/random/... */
 +	dir = pfs_create_dir(dir, "random", NULL, NULL, NULL, 0);
 +	pfs_create_file(dir, "uuid", &linprocfs_douuid,
 +	    NULL, NULL, NULL, PFS_RD);
 +
  	return (0);
  }
  
 
 Modified: stable/10/usr.bin/makewhatis/makewhatis.1
 ==============================================================================
 --- stable/10/usr.bin/makewhatis/makewhatis.1	Thu Mar 13 01:16:51 2014	(r263100)
 +++ stable/10/usr.bin/makewhatis/makewhatis.1	Thu Mar 13 03:42:00 2014	(r263101)
 @@ -24,12 +24,12 @@
  .\"
  .\" $FreeBSD$
  .\"
 -.Dd December 3, 2005
 -.Dt MAKEWHATIS 1
 +.Dd December 8, 2013
 +.Dt MAKEWHATIS 8
  .Os
  .Sh NAME
  .Nm makewhatis
 -.Nd "create whatis database"
 +.Nd create whatis database
  .Sh SYNOPSIS
  .Nm
  .Op Fl a
 @@ -98,9 +98,6 @@ option is used.
  .It Ev MACHINE
  If set, its value is used to override the current
  machine type when searching machine specific subdirectories.
 -.It Ev MACHINE_ARCH
 -If set, its value is used to override the current
 -architecture when searching architecture specific subdirectories.
  .It Ev MANPATH
  Determines the set of directories to be processed if none are given on
  the command line.
 @@ -133,4 +130,6 @@ program was originally written in Perl a
  The current version of
  .Nm
  was rewritten in C by
 -.An John Rochester .
 +.An John Rochester
 +with additional contributions by
 +.An Franco Fichtner Aq Mt franco@lastsummer.de .
 
 Modified: stable/10/usr.bin/makewhatis/makewhatis.c
 ==============================================================================
 --- stable/10/usr.bin/makewhatis/makewhatis.c	Thu Mar 13 01:16:51 2014	(r263100)
 +++ stable/10/usr.bin/makewhatis/makewhatis.c	Thu Mar 13 03:42:00 2014	(r263101)
 @@ -1,5 +1,6 @@
  /*-
   * Copyright (c) 2002 John Rochester
 + * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
 @@ -24,21 +25,19 @@
   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + *
 + * $FreeBSD$
   */
  
 -#include <sys/cdefs.h>
 -__FBSDID("$FreeBSD$");
 -
 +#include <sys/tree.h>
  #include <sys/types.h>
 -#include <sys/stat.h>
  #include <sys/param.h>
  #include <sys/queue.h>
 -#include <sys/utsname.h>
 +#include <sys/stat.h>
  
  #include <ctype.h>
  #include <dirent.h>
  #include <err.h>
 -#include <stddef.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
 @@ -52,16 +51,56 @@ __FBSDID("$FreeBSD$");
  static char blank[] = 		"";
  
  /*
 - * Information collected about each man page in a section.
 + * Information collected about each man page alias.
 + */
 +struct page_alias {
 +	RB_ENTRY(page_alias) entry;
 +	char *filename;
 +	char *name;
 +	char *suffix;
 +	int gzipped;
 +};
 +
 +/*
 + * Information collected about each unique man page.
   */
  struct page_info {
 -	char *	filename;
 -	char *	name;
 -	char *	suffix;
 -	int	gzipped;
 -	ino_t	inode;
 +	RB_HEAD(page_alias_tree, page_alias) head;
 +	RB_ENTRY(page_info) entry;
 +	ino_t inode;
  };
  
 +static RB_HEAD(page_info_tree, page_info) page_head = RB_INITIALIZER(&page_head);
 +
 +/*
 + * Sorts page info by inode number.
 + */
 +static int
 +infosort(const struct page_info *a, const struct page_info *b)
 +{
 +	return (memcmp(&a->inode, &b->inode, sizeof(a->inode)));
 +}
 +
 +RB_PROTOTYPE(page_info_tree, page_info, entry, infosort);
 +RB_GENERATE(page_info_tree, page_info, entry, infosort);
 +
 +/*
 + * Sorts page alias first by suffix, then name.
 + */
 +static int
 +aliassort(const struct page_alias *a, const struct page_alias *b)
 +{
 +	int ret = strcmp(a->suffix, b->suffix);
 +	if (ret) {
 +		return (ret);
 +	}
 +
 +	return (strcmp(a->name, b->name));
 +}
 +
 +RB_PROTOTYPE(page_alias_tree, page_alias, entry, aliassort);
 +RB_GENERATE(page_alias_tree, page_alias, entry, aliassort);
 +
  /*
   * An entry kept for each visited directory.
   */
 @@ -100,7 +139,7 @@ static const char *whatis_name="whatis";
  static char *common_output;		/* -o option: the single output file */
  static char *locale;			/* user's locale if -L is used */
  static char *lang_locale;		/* short form of locale */
 -static const char *machine, *machine_arch;
 +static const char *machine;
  
  static int exit_code;			/* exit code to use when finished */
  static SLIST_HEAD(, visited_dir) visited_dirs =
 @@ -132,62 +171,66 @@ static char mdoc_commands[] = "ArDvErEvF
  static void
  free_page_info(struct page_info *info)
  {
 -	free(info->filename);
 -	free(info->name);
 -	free(info->suffix);
 +	struct page_alias *alias;
 +
 +	while ((alias = RB_ROOT(&info->head))) {
 +		RB_REMOVE(page_alias_tree, &info->head, alias);
 +		free(alias->filename);
 +		free(alias->suffix);
 +		free(alias->name);
 +		free(alias);
 +	}
 +
  	free(info);
  }
  
  /*
 - * Allocates and fills in a new struct page_info given the
 - * name of the man section directory and the dirent of the file.
 - * If the file is not a man page, returns NULL.
 + * Allocates and fills in a new struct page_alias given the
 + * full file name of the man page and its dirent.
 + * If the file is not a man page, nothing is added.
   */
 -static struct page_info *
 -new_page_info(char *dir, struct dirent *dirent)
 +static void
 +new_page_alias(struct page_info *info, char *filename, struct dirent *dirent)
  {
 -	struct page_info *info;
 -	int basename_length;
 +	int gzipped, basename_length;
 +	struct page_alias *alias;
  	char *suffix;
 -	struct stat st;
  
 -	info = (struct page_info *) malloc(sizeof(struct page_info));
 -	if (info == NULL)
 -		err(1, "malloc");
  	basename_length = strlen(dirent->d_name);
  	suffix = &dirent->d_name[basename_length];
 -	asprintf(&info->filename, "%s/%s", dir, dirent->d_name);
 -	if ((info->gzipped = basename_length >= 4 && strcmp(&dirent->d_name[basename_length - 3], ".gz") == 0)) {
 +
 +	gzipped = basename_length >= 4 &&
 +	    strcmp(&dirent->d_name[basename_length - 3], ".gz") == 0;
 +	if (gzipped) {
  		suffix -= 3;
  		*suffix = '\0';
  	}
 +
  	for (;;) {
  		if (--suffix == dirent->d_name || !isalnum(*suffix)) {
 -			if (*suffix == '.')
 +			if (*suffix == '.') {
  				break;
 -			if (verbose)
 -				warnx("%s: invalid man page name", info->filename);
 -			free(info->filename);
 -			free(info);
 -			return NULL;
 +			}
 +			if (verbose) {
 +				warnx("%s: invalid man page name", filename);
 +			}
 +			return;
  		}
  	}
 +
  	*suffix++ = '\0';
 -	info->name = strdup(dirent->d_name);
 -	info->suffix = strdup(suffix);
 -	if (stat(info->filename, &st) < 0) {
 -		warn("%s", info->filename);
 -		free_page_info(info);
 -		return NULL;
 -	}
 -	if (!S_ISREG(st.st_mode)) {
 -		if (verbose && !S_ISDIR(st.st_mode))
 -			warnx("%s: not a regular file", info->filename);
 -		free_page_info(info);
 -		return NULL;
 +
 +	alias = malloc(sizeof(*alias));
 +	if (alias == NULL) {
 +		err(1, "malloc");
  	}
 -	info->inode = st.st_ino;
 -	return info;
 +
 +	alias->name = strdup(dirent->d_name);	/* XXX unsafe */
 +	alias->filename = strdup(filename);	/* XXX unsafe */
 +	alias->suffix = strdup(suffix);		/* XXX unsafe */
 +	alias->gzipped = gzipped;
 +
 +	RB_INSERT(page_alias_tree, &info->head, alias);
  }
  
  /*
 @@ -206,10 +249,10 @@ static struct sbuf *
  new_sbuf(void)
  {
  	struct sbuf *sbuf = (struct sbuf *) malloc(sizeof(struct sbuf));
 -	sbuf->content = (char *) malloc(LINE_ALLOC);
 +	sbuf->content = malloc(LINE_ALLOC);
  	sbuf->last = sbuf->content + LINE_ALLOC - 1;
  	sbuf_clear(sbuf);
 -	return sbuf;
 +	return(sbuf);
  }
  
  /*
 @@ -227,7 +270,7 @@ sbuf_need(struct sbuf *sbuf, int nchars)
  		size *= 2;
  		cntsize = sbuf->end - sbuf->content;
  
 -		new_content = (char *)malloc(size);
 +		new_content = malloc(size);
  		memcpy(new_content, sbuf->content, cntsize);
  		free(sbuf->content);
  		sbuf->content = new_content;
 @@ -288,29 +331,7 @@ static char *
  sbuf_content(struct sbuf *sbuf)
  {
  	*sbuf->end = '\0';
 -	return sbuf->content;
 -}
 -
 -/*
 - * Returns true if no man page exists in the directory with
 - * any of the names in the StringList.
 - */
 -static int
 -no_page_exists(char *dir, StringList *names, char *suffix)
 -{
 -	char path[MAXPATHLEN];
 -	size_t i;
 -
 -	for (i = 0; i < names->sl_cur; i++) {
 -		snprintf(path, sizeof path, "%s/%s.%s.gz", dir, names->sl_str[i], suffix);
 -		if (access(path, F_OK) < 0) {
 -			path[strlen(path) - 3] = '\0';
 -			if (access(path, F_OK) < 0)
 -				continue;
 -		}
 -		return 0;
 -	}
 -	return 1;
 +	return(sbuf->content);
  }
  
  static void
 @@ -337,7 +358,7 @@ open_output(char *name)
  		if (output == NULL) {
  			warn("%s", name);
  			exit_code = 1;
 -			return NULL;
 +			return(NULL);
  		}
  		while (fgets(line, sizeof line, output) != NULL) {
  			line[strlen(line) - 1] = '\0';
 @@ -352,15 +373,15 @@ open_output(char *name)
  	if (output == NULL) {
  		warn("%s", name);
  		exit_code = 1;
 -		return NULL;
 +		return(NULL);
  	}
 -	return output;
 +	return(output);
  }
  
  static int
  linesort(const void *a, const void *b)
  {
 -	return strcmp((*(const char * const *)a), (*(const char * const *)b));
 +	return(strcmp((*(const char * const *)a), (*(const char * const *)b)));
  }
  
  /*
 @@ -372,7 +393,8 @@ finish_output(FILE *output, char *name)
  	size_t i;
  	char *prev = NULL;
  
 -	qsort(whatis_lines->sl_str, whatis_lines->sl_cur, sizeof(char *), linesort);
 +	qsort(whatis_lines->sl_str, whatis_lines->sl_cur, sizeof(char *),
 +	      linesort);
  	for (i = 0; i < whatis_lines->sl_cur; i++) {
  		char *line = whatis_lines->sl_str[i];
  		if (i > 0 && strcmp(line, prev) == 0)
 @@ -395,7 +417,7 @@ open_whatis(char *mandir)
  	char filename[MAXPATHLEN];
  
  	snprintf(filename, sizeof filename, "%s/%s", mandir, whatis_name);
 -	return open_output(filename);
 +	return(open_output(filename));
  }
  
  static void
 @@ -419,20 +441,20 @@ already_visited(char *dir)
  	if (stat(dir, &st) < 0) {
  		warn("%s", dir);
  		exit_code = 1;
 -		return 1;
 +		return(1);
  	}
  	SLIST_FOREACH(visit, &visited_dirs, next) {
  		if (visit->inode == st.st_ino &&
  		    visit->device == st.st_dev) {
  			warnx("already visited %s", dir);
 -			return 1;
 +			return(1);
  		}
  	}
  	visit = (struct visited_dir *) malloc(sizeof(struct visited_dir));
  	visit->device = st.st_dev;
  	visit->inode = st.st_ino;
  	SLIST_INSERT_HEAD(&visited_dirs, visit, next);
 -	return 0;
 +	return(0);
  }
  
  /*
 @@ -446,7 +468,7 @@ trim_rhs(char *str)
  	while (--rhs > str && isspace(*rhs))
  		;
  	*++rhs = '\0';
 -	return rhs;
 +	return(rhs);
  }
  
  /*
 @@ -457,7 +479,7 @@ skip_spaces(char *s)
  {
  	while (*s != '\0' && isspace(*s))
  		s++;
 -	return s;
 +	return(s);
  }
  
  /*
 @@ -467,10 +489,10 @@ static int
  only_digits(char *line)
  {
  	if (!isdigit(*line++))
 -		return 0;
 +		return(0);
  	while (isdigit(*line))
  		line++;
 -	return *line == '\0';
 +	return(*line == '\0');
  }
  
  /*
 @@ -487,7 +509,7 @@ name_section_line(char *line, const char
  	const char **title;
  
  	if (strncmp(line, section_start, 3) != 0)
 -		return 0;
 +		return(0);
  	line = skip_spaces(line + 3);
  	rhs = trim_rhs(line);
  	if (*line == '"') {
 @@ -497,8 +519,8 @@ name_section_line(char *line, const char
  	}
  	for (title = name_section_titles; *title != NULL; title++)
  		if (strcmp(*title, line) == 0)
 -			return 1;
 -	return 0;
 +			return(1);
 +	return(0);
  }
  
  /*
 @@ -518,7 +540,7 @@ de_nroff_copy(char *from, char *to, int 
  			switch (*++from) {
  			case '(':
  				if (strncmp(&from[1], "em", 2) == 0 ||
 -						strncmp(&from[1], "mi", 2) == 0) {
 +				    strncmp(&from[1], "mi", 2) == 0) {
  					from += 3;
  					continue;
  				}
 @@ -534,7 +556,8 @@ de_nroff_copy(char *from, char *to, int 
  				if (*++from == '(')
  					from += 3;
  				else if (*from == '[') {
 -					while (*++from != ']' && from < from_end);
 +					while (*++from != ']' && from < from_end)
 +						;
  					from++;
  				} else
  					from++;
 @@ -547,7 +570,7 @@ de_nroff_copy(char *from, char *to, int 
  		}
  		*to++ = *from++;
  	}
 -	return to;
 +	return(to);
  }
  
  /*
 @@ -594,6 +617,38 @@ process_man_line(char *line)
  	}
  }
  
 +struct mdoc_text {
 +	const char *mdoc;
 +	const char *text;
 +};
 +
 +static int
 +process_mdoc_macro(char *line)
 +{
 +	static const struct mdoc_text list[] = {
 +		{ ".At", "AT&T UNIX" },
 +		{ ".Bsx", "BSD/OS" },
 +		{ ".Bx", "BSD" },
 +		{ ".Dx", "DragonFly" },
 +		{ ".Fx", "FreeBSD" },
 +		{ ".Nx", "NetBSD" },
 +		{ ".Ox", "OpenBSD" },
 +		{ ".Ux", "UNIX" },
 +	};
 +	unsigned int i;
 +
 +	for (i = 0; i < sizeof(list) / sizeof(list[0]); ++i) {
 +		if (!strcmp(line, list[i].mdoc)) {
 +			sbuf_append(whatis_proto, list[i].text,
 +			    strlen(list[i].text));
 +			sbuf_append(whatis_proto, " ", 1);
 +			return (1);
 +		}
 +	}
 +
 +	return (0);
 +}
 +
  /*
   * Processes a new-style mdoc(7) line.
   */
 @@ -613,6 +668,9 @@ process_mdoc_line(char *line)
  		sbuf_append(whatis_proto, " ", 1);
  		return;
  	}
 +	if (process_mdoc_macro(line)) {
 +		return;
 +	}
  	xref = strncmp(line, ".Xr", 3) == 0;
  	line += 3;
  	while ((line = skip_spaces(line)) < line_end) {
 @@ -663,27 +721,6 @@ process_mdoc_line(char *line)
  		sbuf_append(whatis_proto, " ", 1);
  }
  
 -/*
 - * Collects a list of comma-separated names from the text.
 - */
 -static void
 -collect_names(StringList *names, char *text)
 -{
 -	char *arg;
 -
 -	for (;;) {
 -		arg = text;
 -		text = strchr(text, ',');
 -		if (text != NULL)
 -			*text++ = '\0';
 -		sl_add(names, arg);
 -		if (text == NULL)
 -			return;
 -		if (*text == ' ')
 -			text++;
 -	}
 -}
 -
  enum { STATE_UNKNOWN, STATE_MANSTYLE, STATE_MDOCNAME, STATE_MDOCDESC };
  
  /*
 @@ -691,25 +728,33 @@ enum { STATE_UNKNOWN, STATE_MANSTYLE, ST
   * to whatis_lines.
   */
  static void
 -process_page(struct page_info *page, char *section_dir)
 +process_page(struct page_info *info)
  {
 -	gzFile in;
 -	char buffer[4096];
 -	char *line;
 -	StringList *names;
 -	char *descr;
  	int state = STATE_UNKNOWN;
 -	size_t i;
 +	struct page_alias *alias;
 +	char *line, *descr;
 +	char buffer[4096];
 +	gzFile in;
 +
 +	/*
 +	 * Only read the page once for each inode.  It's
 +	 * safe to assume that page->list is set.
 +	 */
 +	alias = RB_MIN(page_alias_tree, &info->head);
 +
 +	if (verbose) {
 +		fprintf(stderr, "\treading %s\n", alias->filename);
 +	}
  
  	sbuf_clear(whatis_proto);
 -	if ((in = gzopen(page->filename, "r")) == NULL) {
 -		warn("%s", page->filename);
 +	if ((in = gzopen(alias->filename, "r")) == NULL) {
 +		warn("%s", alias->filename);
  		exit_code = 1;
  		return;
  	}
 -	while (gzgets(in, buffer, sizeof buffer) != NULL) {
 +	while (gzgets(in, buffer, sizeof(buffer)) != NULL) {
  		line = buffer;
 -		if (strncmp(line, ".\\\"", 3) == 0)		/* ignore comments */
 +		if (strncmp(line, ".\\\"", 3) == 0)	/* ignore comments */
  			continue;
  		switch (state) {
  		/*
 @@ -779,7 +824,9 @@ process_page(struct page_info *page, cha
  		descr = strchr(line, ' ');
  		if (descr == NULL) {
  			if (verbose)
 -				fprintf(stderr, "	ignoring junk description \"%s\"\n", line);
 +				fprintf(stderr,
 +					"\tignoring junk description \"%s\"\n",
 +					line);
  			return;
  		}
  		*descr++ = '\0';
 @@ -787,19 +834,16 @@ process_page(struct page_info *page, cha
  		*descr = '\0';
  		descr += 3;
  	}
 -	names = sl_init();
 -	collect_names(names, line);
  	sbuf_clear(whatis_final);
 -	if (!sl_find(names, page->name) && no_page_exists(section_dir, names, page->suffix)) {
 +	RB_FOREACH(alias, page_alias_tree, &info->head) {
  		/*
 -		 * Add the page name since that's the only thing that
 -		 * man(1) will find.
 +		 * This won't append names stored in `line'.
 +		 * The reason for that is that we cannot be sure
 +		 * which section they belong to unless we have
 +		 * a real alias (via MLINKS) in this list.
  		 */
 -		add_whatis_name(page->name, page->suffix);
 +		add_whatis_name(alias->name, alias->suffix);
  	}
 -	for (i = 0; i < names->sl_cur; i++)
 -		add_whatis_name(names->sl_str[i], page->suffix);
 -	sl_free(names, 0);
  	sbuf_retract(whatis_final, 2);		/* remove last ", " */
  	while (sbuf_length(whatis_final) < indent)
  		sbuf_append(whatis_final, " ", 1);
 @@ -809,33 +853,19 @@ process_page(struct page_info *page, cha
  }
  
  /*
 - * Sorts pages first by inode number, then by name.
 - */
 -static int
 -pagesort(const void *a, const void *b)
 -{
 -	const struct page_info *p1 = *(struct page_info * const *) a;
 -	const struct page_info *p2 = *(struct page_info * const *) b;
 -	if (p1->inode == p2->inode)
 -		return strcmp(p1->name, p2->name);
 -	return p1->inode - p2->inode;
 -}
 -
 -/*
   * Processes a single man section.
   */
  static void
  process_section(char *section_dir)
  {
  	struct dirent **entries;
 +	struct page_info *info;
  	int nentries;
 -	struct page_info **pages;
 -	int npages = 0;
  	int i;
 -	ino_t prev_inode = 0;
  
 -	if (verbose)
 +	if (verbose) {
  		fprintf(stderr, "  %s\n", section_dir);
 +	}
  
  	/*
  	 * scan the man section directory for pages
 @@ -846,33 +876,55 @@ process_section(char *section_dir)
  		exit_code = 1;
  		return;
  	}
 +
  	/*
  	 * collect information about man pages
  	 */
 -	pages = (struct page_info **) calloc(nentries, sizeof(struct page_info *));
  	for (i = 0; i < nentries; i++) {
 -		struct page_info *info = new_page_info(section_dir, entries[i]);
 -		if (info != NULL)
 -			pages[npages++] = info;
 +		struct page_info ref;
 +		char *filename;
 +		struct stat st;
 +
 +		if (asprintf(&filename, "%s/%s", section_dir,
 +		    entries[i]->d_name) < 0) {
 +			err(1, "malloc");
 +		}
 +
 +		if (stat(filename, &st) < 0) {
 +			warn("%s", filename);
 +			goto process_section_next;
 +		}
 +
 +		if (!S_ISREG(st.st_mode)) {
 +			if (verbose && !S_ISDIR(st.st_mode))
 +			    warnx("%s: not a regular file", filename);
 +			goto process_section_next;
 +		}
 +
 +		ref.inode = st.st_ino;
 +
 +		info = RB_FIND(page_info_tree, &page_head, &ref);
 +		if (info == NULL) {
 +			info = malloc(sizeof(*info));
 +			if (info == NULL) {
 +				err(1, "malloc");
 +			}
 +
 +			bzero(info, sizeof(*info));
 +			info->inode = st.st_ino;
 +			RB_INIT(&info->head);
 +
 +			RB_INSERT(page_info_tree, &page_head, info);
 +		}
 +
 +		new_page_alias(info, filename, entries[i]);
 +
 +process_section_next:
 +
  		free(entries[i]);
 +		free(filename);
  	}
  	free(entries);
 -	qsort(pages, npages, sizeof(struct page_info *), pagesort);
 -	/*
 -	 * process each unique page
 -	 */
 -	for (i = 0; i < npages; i++) {
 -		struct page_info *page = pages[i];
 -		if (page->inode != prev_inode) {
 -			prev_inode = page->inode;
 -			if (verbose)
 -				fprintf(stderr, "	reading %s\n", page->filename);
 -			process_page(page, section_dir);
 -		} else if (verbose)
 -			fprintf(stderr, "	skipping %s, duplicate\n", page->filename);
 -		free_page_info(page);
 -	}
 -	free(pages);
  }
  
  /*
 @@ -884,12 +936,12 @@ select_sections(const struct dirent *ent
  	const char *p = &entry->d_name[3];
  
  	if (strncmp(entry->d_name, "man", 3) != 0)
 -		return 0;
 +		return(0);
  	while (*p != '\0') {
  		if (!isalnum(*p++))
 -			return 0;
 +			return(0);
  	}
 -	return 1;
 +	return(1);
  }
  
  /*
 @@ -900,6 +952,7 @@ static void
  process_mandir(char *dir_name)
  {
  	struct dirent **entries;
 +	struct page_info *info;
  	int nsections;
  	FILE *fp = NULL;
  	int i;
 @@ -919,21 +972,26 @@ process_mandir(char *dir_name)
  		return;
  	for (i = 0; i < nsections; i++) {
  		char section_dir[MAXPATHLEN];
 -		snprintf(section_dir, sizeof section_dir, "%s/%s", dir_name, entries[i]->d_name);
 +		snprintf(section_dir, sizeof section_dir, "%s/%s", dir_name,
 +			 entries[i]->d_name);
  		process_section(section_dir);
  		snprintf(section_dir, sizeof section_dir, "%s/%s/%s", dir_name,
 -		    entries[i]->d_name, machine);
 +			 entries[i]->d_name, machine);
  		if (stat(section_dir, &st) == 0 && S_ISDIR(st.st_mode))
  			process_section(section_dir);
 -		if (strcmp(machine_arch, machine) != 0) {
 -			snprintf(section_dir, sizeof section_dir, "%s/%s/%s",
 -			    dir_name, entries[i]->d_name, machine_arch);
 -			if (stat(section_dir, &st) == 0 && S_ISDIR(st.st_mode))
 -				process_section(section_dir);
 -		}
  		free(entries[i]);
  	}
  	free(entries);
 +
 +	/*
 +	 * process and free all pages
 +	 */
 +	while ((info = RB_ROOT(&page_head))) {
 +		RB_REMOVE(page_info_tree, &page_head, info);
 +		process_page(info);
 +		free_page_info(info);
 +	}
 +
  	if (common_output == NULL)
  		finish_whatis(fp, dir_name);
  }
 @@ -1003,7 +1061,9 @@ main(int argc, char **argv)
  				char *sep = strchr(locale, '_');
  				if (sep != NULL && isupper(sep[1]) &&
  				    isupper(sep[2])) {
 -					asprintf(&lang_locale, "%.*s%s", (int)(ptrdiff_t)(sep - locale), locale, &sep[3]);
 +					asprintf(&lang_locale, "%.*s%s",
 +					    (int)(sep - locale),
 +					    locale, &sep[3]);
  				}
  			}
  			break;
 @@ -1021,16 +1081,8 @@ main(int argc, char **argv)
  	whatis_proto = new_sbuf();
  	whatis_final = new_sbuf();
  
 -	if ((machine = getenv("MACHINE")) == NULL) {
 -		static struct utsname utsname;
 -
 -		if (uname(&utsname) == -1)
 -			err(1, "uname");
 -		machine = utsname.machine;
 -	}
 -
 -	if ((machine_arch = getenv("MACHINE_ARCH")) == NULL)
 -		machine_arch = MACHINE_ARCH;
 +	if ((machine = getenv("MACHINE")) == NULL)
 +		machine = MACHINE;
  
  	if (common_output != NULL && (fp = open_output(common_output)) == NULL)
  		err(1, "%s", common_output);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/186187: commit references a PR
Date: Thu, 13 Mar 2014 03:57:46 +0000 (UTC)

 Author: eadler
 Date: Thu Mar 13 03:57:33 2014
 New Revision: 263103
 URL: http://svnweb.freebsd.org/changeset/base/263103
 
 Log:
   MFC r262539:
   linprocfs: add support for /sys/kernel/random/uuid
   
   PR:		kern/186187
 
 Modified:
   stable/9/sys/compat/linprocfs/linprocfs.c
 Directory Properties:
   stable/9/sys/   (props changed)
 
 Modified: stable/9/sys/compat/linprocfs/linprocfs.c
 ==============================================================================
 --- stable/9/sys/compat/linprocfs/linprocfs.c	Thu Mar 13 03:42:24 2014	(r263102)
 +++ stable/9/sys/compat/linprocfs/linprocfs.c	Thu Mar 13 03:57:33 2014	(r263103)
 @@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/time.h>
  #include <sys/tty.h>
  #include <sys/user.h>
 +#include <sys/uuid.h>
  #include <sys/vmmeter.h>
  #include <sys/vnode.h>
  #include <sys/bus.h>
 @@ -1347,6 +1348,22 @@ linprocfs_dofdescfs(PFS_FILL_ARGS)
  	return (0);
  }
  
 +
 +/*
 + * Filler function for proc/sys/kernel/random/uuid
 + */
 +static int
 +linprocfs_douuid(PFS_FILL_ARGS)
 +{
 +	struct uuid uuid;
 +
 +	kern_uuidgen(&uuid, 1);
 +	sbuf_printf_uuid(sb, &uuid);
 +	sbuf_printf(sb, "\n");
 +	return(0);
 +}
 +
 +
  /*
   * Constructor
   */
 @@ -1446,6 +1463,11 @@ linprocfs_init(PFS_INIT_ARGS)
  	pfs_create_file(dir, "sem", &linprocfs_dosem,
  	    NULL, NULL, NULL, PFS_RD);
  
 +	/* /proc/sys/kernel/random/... */
 +	dir = pfs_create_dir(dir, "random", NULL, NULL, NULL, 0);
 +	pfs_create_file(dir, "uuid", &linprocfs_douuid,
 +	    NULL, NULL, NULL, PFS_RD);
 +
  	return (0);
  }
  
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
