libbsd: Branch 'master' - 5 commits

Guillem Jover guillem at kemper.freedesktop.org
Tue May 19 19:28:29 PDT 2009


 Makefile             |    7 
 Versions             |    8 
 include/bsd/bsd.h    |    2 
 include/bsd/cdefs.h  |    2 
 include/bsd/err.h    |    2 
 include/bsd/getopt.h |    2 
 include/bsd/inet.h   |    2 
 include/bsd/random.h |    2 
 include/bsd/stdlib.h |    6 
 include/bsd/string.h |    4 
 include/nlist.h      |   38 ++++
 man/nlist.3          |   77 +++++++++
 man/strmode.3        |  144 +++++++++++++++++
 src/bsd_getopt.c     |    2 
 src/err.c            |    2 
 src/fgetln.c         |   21 +-
 src/local-elf.h      |  197 +++++++++++++++++++++++
 src/nlist.c          |  419 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/progname.c       |    2 
 src/strmode.c        |  149 ++++++++++++++++++
 20 files changed, 1063 insertions(+), 25 deletions(-)

New commits:
commit 1f0b016e97611a35151eca4952277211a0ee4656
Author: Guillem Jover <guillem at hadrons.org>
Date:   Wed May 20 04:20:21 2009 +0200

    Use UTF-8 copyright symbols for non-imported files

diff --git a/include/bsd/bsd.h b/include/bsd/bsd.h
index 0d81a3c..2956dc6 100644
--- a/include/bsd/bsd.h
+++ b/include/bsd/bsd.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005, 2006 Guillem Jover
+ * Copyright © 2004, 2005, 2006 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/include/bsd/cdefs.h b/include/bsd/cdefs.h
index 3b6446e..9d5920c 100644
--- a/include/bsd/cdefs.h
+++ b/include/bsd/cdefs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005, 2006 Guillem Jover
+ * Copyright © 2004, 2005, 2006 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/include/bsd/err.h b/include/bsd/err.h
index fd23bfa..b8f9c82 100644
--- a/include/bsd/err.h
+++ b/include/bsd/err.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Robert Millan
+ * Copyright © 2006 Robert Millan
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/include/bsd/getopt.h b/include/bsd/getopt.h
index 2f772f0..4d68b55 100644
--- a/include/bsd/getopt.h
+++ b/include/bsd/getopt.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Robert Millan
+ * Copyright © 2006 Robert Millan
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/include/bsd/inet.h b/include/bsd/inet.h
index d9a63a5..14ea256 100644
--- a/include/bsd/inet.h
+++ b/include/bsd/inet.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Guillem Jover
+ * Copyright © 2008 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/include/bsd/random.h b/include/bsd/random.h
index 9999a8d..578c9be 100644
--- a/include/bsd/random.h
+++ b/include/bsd/random.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005 Guillem Jover
+ * Copyright © 2004, 2005 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/include/bsd/stdlib.h b/include/bsd/stdlib.h
index 16376cb..b01d970 100644
--- a/include/bsd/stdlib.h
+++ b/include/bsd/stdlib.h
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2005 Aurelien Jarno
- * Copyright (C) 2006 Robert Millan
- * Copyright (C) 2008 Guillem Jover
+ * Copyright © 2005 Aurelien Jarno
+ * Copyright © 2006 Robert Millan
+ * Copyright © 2008 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/include/bsd/string.h b/include/bsd/string.h
index 185a42d..e660369 100644
--- a/include/bsd/string.h
+++ b/include/bsd/string.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005, 2009 Guillem Jover
+ * Copyright © 2004, 2005, 2009 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/include/nlist.h b/include/nlist.h
index 95af7d8..0f2fa20 100644
--- a/include/nlist.h
+++ b/include/nlist.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Guillem Jover
+ * Copyright © 2009 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/src/bsd_getopt.c b/src/bsd_getopt.c
index 73edae5..1c878ed 100644
--- a/src/bsd_getopt.c
+++ b/src/bsd_getopt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Robert Millan
+ * Copyright © 2006 Robert Millan
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/src/err.c b/src/err.c
index 7317b92..c7bb416 100644
--- a/src/err.c
+++ b/src/err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Robert Millan
+ * Copyright © 2006 Robert Millan
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/src/fgetln.c b/src/fgetln.c
index 33b261b..6e3d000 100644
--- a/src/fgetln.c
+++ b/src/fgetln.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2005 Hector Garcia Alvarez
- * Copyright (C) 2005, 2008, 2009 Guillem Jover
+ * Copyright © 2005 Hector Garcia Alvarez
+ * Copyright © 2005, 2008, 2009 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/src/local-elf.h b/src/local-elf.h
index 1ac0fc8..b9484b6 100644
--- a/src/local-elf.h
+++ b/src/local-elf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Guillem Jover
+ * Copyright © 2009 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/src/progname.c b/src/progname.c
index 69a060a..9415f17 100644
--- a/src/progname.c
+++ b/src/progname.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Robert Millan
+ * Copyright © 2006 Robert Millan
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
commit dcaec44a6fd4ede2b8d8050a7c05185c28f66917
Author: Guillem Jover <guillem at hadrons.org>
Date:   Wed May 20 04:11:57 2009 +0200

    Add nlist function

diff --git a/Makefile b/Makefile
index 393a050..11564e2 100644
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,7 @@ LIB_SRCS := \
 	strmode.c \
 	strlcat.c strlcpy.c \
 	fmtcheck.c \
+	nlist.c \
 	progname.c \
 	vis.c unvis.c
 LIB_SRCS := $(patsubst %,src/%,$(LIB_SRCS))
diff --git a/Versions b/Versions
index 21123b6..76d8163 100644
--- a/Versions
+++ b/Versions
@@ -37,5 +37,8 @@ LIBBSD_0.0 {
 
 LIBBSD_0.1 {
     strmode;
+
+    __fdnlist; /* Private symbol, but libkvm uses it. */
+    nlist;
 } LIBBSD_0.0;
 
diff --git a/include/nlist.h b/include/nlist.h
new file mode 100644
index 0000000..95af7d8
--- /dev/null
+++ b/include/nlist.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 Guillem Jover
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 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.
+ */
+
+#ifndef LIBBSD_NLIST_H
+#define LIBBSD_NLIST_H
+
+#include <sys/cdefs.h>
+#include <sys/a.out.h>
+
+__BEGIN_DECLS
+extern int nlist(const char *filename, struct nlist *list);
+__END_DECLS
+
+#endif
+
diff --git a/man/nlist.3 b/man/nlist.3
new file mode 100644
index 0000000..6a9b367
--- /dev/null
+++ b/man/nlist.3
@@ -0,0 +1,77 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY 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.
+.\"
+.\"     @(#)nlist.3	8.3 (Berkeley) 4/19/94
+.\" $FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/nlist.3,v 1.7 2001/10/01 16:08:51 ru Exp $
+.\"
+.Dd April 19, 1994
+.Dt NLIST 3
+.Os
+.Sh NAME
+.Nm nlist
+.Nd retrieve symbol table name list from an executable file
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In nlist.h
+.Ft int
+.Fn nlist "const char *filename" "struct nlist *nl"
+.Sh DESCRIPTION
+The
+.Fn nlist
+function
+retrieves name list entries from the symbol table of an
+executable file (see
+.Xr a.out 5 ) .
+The argument
+.Fa \&nl
+is set to reference the
+beginning of the list.
+The list is preened of binary and invalid data;
+if an entry in the
+name list is valid, the
+.Fa n_type
+and
+.Fa n_value
+for the entry are copied into the list
+referenced by
+.Fa \&nl .
+No other data is copied.
+The last entry in the list is always
+.Dv NULL .
+.Sh RETURN VALUES
+The number of invalid entries is returned if successful; otherwise,
+if the file
+.Fa filename
+does not exist or is not executable, the returned value is \-1.
+.Sh SEE ALSO
+.Xr a.out 5
+.Sh HISTORY
+A
+.Fn nlist
+function appeared in
+.At v6 .
diff --git a/src/local-elf.h b/src/local-elf.h
new file mode 100644
index 0000000..1ac0fc8
--- /dev/null
+++ b/src/local-elf.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2009 Guillem Jover
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 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.
+ */
+
+#ifndef LIBBSD_LOCAL_ELF_H
+#define LIBBSD_LOCAL_ELF_H
+
+#include <elf.h>
+
+#define IS_ELF(ehdr) \
+	((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+	 (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+	 (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+	 (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+#define ELF_TARG_VER	EV_CURRENT
+
+#if defined(__alpha__)
+
+#define ELF_TARG_MACH	EM_ALPHA
+#define ELF_TARG_CLASS	ELFCLASS64
+#define ELF_TARG_DATA	ELFDATA2LSB
+
+#elif defined(__amd64__)
+
+#define ELF_TARG_MACH	EM_X86_64
+#define ELF_TARG_CLASS	ELFCLASS64
+#define ELF_TARG_DATA	ELFDATA2LSB
+
+#elif defined(__arm__)
+
+#define ELF_TARG_MACH	EM_ARM
+#define ELF_TARG_CLASS	ELFCLASS32
+#if defined(__ARMEB__)
+#define ELF_TARG_DATA	ELFDATA2MSB
+#else
+#define ELF_TARG_DATA	ELFDATA2LSB
+#endif
+
+#elif defined(__avr32__)
+
+#ifndef EM_AVR32
+#define EM_AVR32	0x18ad
+#endif
+#define ELF_TARG_MACH	EM_AVR32
+#define ELF_TARG_CLASS	ELFCLASS32
+#if define(__LITTLE_ENDIAN__)
+#define ELF_TARG_DATA	ELFDATA2LSB
+#elif defined(__BIG_ENDIAN__)
+#define ELF_TARG_DATA	ELFDATA2LMSB
+#else
+#error Unknown AVR32 endianness
+#endif
+
+#elif defined(__hppa__)
+
+#define ELF_TARG_MACH	EM_PARISC
+#define ELF_TARG_CLASS	ELFCLASS32
+#define ELF_TARG_DATA	ELFDATA2MSB
+
+#elif defined(__i386__)
+
+#define ELF_TARG_MACH	EM_386
+#define ELF_TARG_CLASS	ELFCLASS32
+#define ELF_TARG_DATA	ELFDATA2LSB
+
+#elif defined(__ia64__)
+
+#define ELF_TARG_MACH	EM_IA_64
+#define ELF_TARG_CLASS	ELFCLASS64
+#define ELF_TARG_DATA	ELFDATA2LSB
+
+#elif defined(__m32r__)
+
+#define ELF_TARG_MACH	EM_M32R
+#define ELF_TARG_CLASS	ELFCLASS32
+#if defined(__LITTLE_ENDIAN__)
+#define ELF_DATA	ELFDATA2LSB
+#elif defined(__BIG_ENDIAN__)
+#define ELF_DATA	ELFDATA2MSB
+#else
+#error Unknown M32R endianness
+#endif
+
+#elif defined(__m68k__)
+
+#define ELF_TARG_MACH	EM_68K
+#define ELF_TARG_CLASS	ELFCLASS32
+#define ELF_TARG_DATA	ELFDATA2MSB
+
+#elif defined(__mips__)
+
+#define ELF_TARG_MACH	EM_MIPS
+#define ELF_TARG_CLASS	ELFCLASS32
+#if defined(__MIPSEB__)
+#define ELF_TARG_DATA	ELFDATA2MSB
+#else
+#define ELF_TARG_DATA	ELFDATA2LSB
+#endif
+
+#elif defined(__powerpc__)
+
+#define ELF_TARG_MACH	EM_PPC
+#define ELF_TARG_CLASS	ELFCLASS32
+#define ELF_TARG_DATA	ELFDATA2MSG
+
+#elif defined(__powerpc64__)
+
+#define ELF_TARG_MACH	EM_PPC64
+#define ELF_TARG_CLASS	ELFCLASS64
+#define ELF_TARG_DATA	ELFDATA2MSG
+
+#elif defined(__sparc__)
+
+#if defined(__arch64__)
+#define ELF_TARG_MACH	EM_SPARCV9
+#define ELF_TARG_CLASS	ELFCLASS64
+#else
+#define ELF_TARG_MACH	EM_SPARC
+#define ELF_TARG_CLASS	ELFCLASS32
+#endif
+#define ELF_TARG_DATA	ELFDATA2MSB
+
+#elif defined(__sh__)
+
+#define ELF_TARG_MACH	EM_SH
+#define ELF_TARG_CLASS	ELFCLASS32
+#if define(__LITTLE_ENDIAN__)
+#define ELF_TARG_DATA	ELFDATA2LSB
+#elif defined(__BIG_ENDIAN__)
+#define ELF_TARG_DATA	ELFDATA2LMSB
+#else
+#error Unknown SH endianness
+#endif
+
+#elif defined(__s390__)
+
+#define ELF_TARG_MACH	EM_S390
+#if defined(__s390x__)
+#define ELF_TARG_CLASS	ELFCLASS64
+#else
+#define ELF_TARG_CLASS	ELFCLASS32
+#endif
+#define ELF_TARG_DATA	ELFDATA2MSG
+
+#else
+
+#error Unknown ELF machine type
+
+#endif
+
+#if ELF_TARG_CLASS == ELFCLASS32
+#define ELF_ST_BIND	ELF32_ST_BIND
+#define ELF_ST_TYPE	ELF32_ST_TYPE
+#define Elf_Word	Elf32_Word
+#define Elf_Sword	Elf32_Sword
+#define Elf_Sym		Elf32_Sym
+#define Elf_Off		Elf32_Off
+#define Elf_Shdr	Elf32_Shdr
+#define Elf_Ehdr	Elf32_Ehdr
+#elif ELF_TARG_CLASS == ELFCLASS64
+#define ELF_ST_BIND	ELF64_ST_BIND
+#define ELF_ST_TYPE	ELF64_ST_TYPE
+#define Elf_Word	Elf64_Word
+#define Elf_Sword	Elf64_Sword
+#define Elf_Sym		Elf64_Sym
+#define Elf_Off		Elf64_Off
+#define Elf_Shdr	Elf64_Shdr
+#define Elf_Ehdr	Elf64_Ehdr
+#else
+#error Unknown ELF class
+#endif
+
+#endif
+
diff --git a/src/nlist.c b/src/nlist.c
new file mode 100644
index 0000000..1db6a06
--- /dev/null
+++ b/src/nlist.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)nlist.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <a.out.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#if !defined(__NO_A_OUT_SUPPORT)
+#define _NLIST_DO_AOUT
+#endif
+#define _NLIST_DO_ELF
+
+#ifdef _NLIST_DO_ELF
+#include "local-elf.h"
+#endif
+
+#define SIZE_T_MAX 0xffffffffU
+
+#ifdef _NLIST_DO_AOUT
+static int __aout_fdnlist(int, struct nlist *);
+#endif
+#ifdef _NLIST_DO_ELF
+static int __elf_fdnlist(int, struct nlist *);
+#endif
+
+/* FIXME: This function is used by libkvm0, so we need to export it.
+   It is not declared in the include files though. */
+int __fdnlist(int, struct nlist *);
+
+int
+nlist(name, list)
+	const char *name;
+	struct nlist *list;
+{
+	int fd, n;
+
+	fd = open(name, O_RDONLY, 0);
+	if (fd < 0)
+		return (-1);
+	n = __fdnlist(fd, list);
+	(void)close(fd);
+	return (n);
+}
+
+static struct nlist_handlers {
+	int	(*fn)(int fd, struct nlist *list);
+} nlist_fn[] = {
+#ifdef _NLIST_DO_AOUT
+	{ __aout_fdnlist },
+#endif
+#ifdef _NLIST_DO_ELF
+	{ __elf_fdnlist },
+#endif
+};
+
+int
+__fdnlist(fd, list)
+	int fd;
+	struct nlist *list;
+{
+	int n = -1, i;
+
+	for (i = 0; i < sizeof(nlist_fn) / sizeof(nlist_fn[0]); i++) {
+		n = (nlist_fn[i].fn)(fd, list);
+		if (n != -1)
+			break;
+	}
+	return (n);
+}
+
+#define	ISLAST(p)	(p->n_un.n_name == 0 || p->n_un.n_name[0] == 0)
+
+#ifdef _NLIST_DO_AOUT
+static int
+__aout_fdnlist(fd, list)
+	int fd;
+	struct nlist *list;
+{
+	struct nlist *p, *symtab;
+	caddr_t strtab, a_out_mmap;
+	off_t stroff, symoff;
+	u_long symsize;
+	int nent;
+	struct exec * exec;
+	struct stat st;
+
+	/* check that file is at least as large as struct exec! */
+	if ((fstat(fd, &st) < 0) || (st.st_size < sizeof(struct exec)))
+		return (-1);
+
+	/* Check for files too large to mmap. */
+	if (st.st_size > SIZE_T_MAX) {
+		errno = EFBIG;
+		return (-1);
+	}
+
+	/*
+	 * Map the whole a.out file into our address space.
+	 * We then find the string table withing this area.
+	 * We do not just mmap the string table, as it probably
+	 * does not start at a page boundary - we save ourselves a
+	 * lot of nastiness by mmapping the whole file.
+	 *
+	 * This gives us an easy way to randomly access all the strings,
+	 * without making the memory allocation permanent as with
+	 * malloc/free (i.e., munmap will return it to the system).
+	 */
+	a_out_mmap = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t)0);
+	if (a_out_mmap == MAP_FAILED)
+		return (-1);
+
+	exec = (struct exec *)a_out_mmap;
+	if (N_BADMAG(*exec)) {
+		munmap(a_out_mmap, (size_t)st.st_size);
+		return (-1);
+	}
+
+	symoff = N_SYMOFF(*exec);
+	symsize = exec->a_syms;
+	stroff = symoff + symsize;
+
+	/* find the string table in our mmapped area */
+	strtab = a_out_mmap + stroff;
+	symtab = (struct nlist *)(a_out_mmap + symoff);
+
+	/*
+	 * clean out any left-over information for all valid entries.
+	 * Type and value defined to be 0 if not found; historical
+	 * versions cleared other and desc as well.  Also figure out
+	 * the largest string length so don't read any more of the
+	 * string table than we have to.
+	 *
+	 * XXX clearing anything other than n_type and n_value violates
+	 * the semantics given in the man page.
+	 */
+	nent = 0;
+	for (p = list; !ISLAST(p); ++p) {
+		p->n_type = 0;
+		p->n_other = 0;
+		p->n_desc = 0;
+		p->n_value = 0;
+		++nent;
+	}
+
+	while (symsize > 0) {
+		int soff;
+
+		symsize-= sizeof(struct nlist);
+		soff = symtab->n_un.n_strx;
+
+
+		if (soff != 0 && (symtab->n_type & N_STAB) == 0)
+			for (p = list; !ISLAST(p); p++)
+				if (!strcmp(&strtab[soff], p->n_un.n_name)) {
+					p->n_value = symtab->n_value;
+					p->n_type = symtab->n_type;
+					p->n_desc = symtab->n_desc;
+					p->n_other = symtab->n_other;
+					if (--nent <= 0)
+						break;
+				}
+		symtab++;
+	}
+	munmap(a_out_mmap, (size_t)st.st_size);
+	return (nent);
+}
+#endif
+
+#ifdef _NLIST_DO_ELF
+static void elf_sym_to_nlist(struct nlist *, Elf_Sym *, Elf_Shdr *, int);
+
+/*
+ * __elf_is_okay__ - Determine if ehdr really
+ * is ELF and valid for the target platform.
+ *
+ * WARNING:  This is NOT an ELF ABI function and
+ * as such its use should be restricted.
+ */
+static int
+__elf_is_okay__(ehdr)
+	Elf_Ehdr *ehdr;
+{
+	int retval = 0;
+	/*
+	 * We need to check magic, class size, endianess,
+	 * and version before we look at the rest of the
+	 * Elf_Ehdr structure.  These few elements are
+	 * represented in a machine independant fashion.
+	 */
+	if (IS_ELF(*ehdr) &&
+	    ehdr->e_ident[EI_CLASS] == ELF_TARG_CLASS &&
+	    ehdr->e_ident[EI_DATA] == ELF_TARG_DATA &&
+	    ehdr->e_ident[EI_VERSION] == ELF_TARG_VER) {
+
+		/* Now check the machine dependant header */
+		if (ehdr->e_machine == ELF_TARG_MACH &&
+		    ehdr->e_version == ELF_TARG_VER)
+			retval = 1;
+	}
+	return retval;
+}
+
+static int
+__elf_fdnlist(fd, list)
+	int fd;
+	struct nlist *list;
+{
+	struct nlist *p;
+	Elf_Off symoff = 0, symstroff = 0;
+	Elf_Word symsize = 0, symstrsize = 0;
+	Elf_Sword cc, i;
+	int nent = -1;
+	int errsave;
+	Elf_Sym sbuf[1024];
+	Elf_Sym *s;
+	Elf_Ehdr ehdr;
+	char *strtab = NULL;
+	Elf_Shdr *shdr = NULL;
+	Elf_Word shdr_size;
+	void *base;
+	struct stat st;
+
+	/* Make sure obj is OK */
+	if (lseek(fd, (off_t)0, SEEK_SET) == -1 ||
+	    read(fd, &ehdr, sizeof(Elf_Ehdr)) != sizeof(Elf_Ehdr) ||
+	    !__elf_is_okay__(&ehdr) ||
+	    fstat(fd, &st) < 0)
+		return (-1);
+
+	/* calculate section header table size */
+	shdr_size = ehdr.e_shentsize * ehdr.e_shnum;
+
+	/* Make sure it's not too big to mmap */
+	if (shdr_size > SIZE_T_MAX) {
+		errno = EFBIG;
+		return (-1);
+	}
+
+	/* mmap section header table */
+	base = mmap(NULL, (size_t)shdr_size, PROT_READ, 0, fd,
+	    (off_t)ehdr.e_shoff);
+	if (base == MAP_FAILED)
+		return (-1);
+	shdr = (Elf_Shdr *)base;
+
+	/*
+	 * Find the symbol table entry and it's corresponding
+	 * string table entry.	Version 1.1 of the ABI states
+	 * that there is only one symbol table but that this
+	 * could change in the future.
+	 */
+	for (i = 0; i < ehdr.e_shnum; i++) {
+		if (shdr[i].sh_type == SHT_SYMTAB) {
+			symoff = shdr[i].sh_offset;
+			symsize = shdr[i].sh_size;
+			symstroff = shdr[shdr[i].sh_link].sh_offset;
+			symstrsize = shdr[shdr[i].sh_link].sh_size;
+			break;
+		}
+	}
+
+	/* Check for files too large to mmap. */
+	if (symstrsize > SIZE_T_MAX) {
+		errno = EFBIG;
+		goto done;
+	}
+	/*
+	 * Map string table into our address space.  This gives us
+	 * an easy way to randomly access all the strings, without
+	 * making the memory allocation permanent as with malloc/free
+	 * (i.e., munmap will return it to the system).
+	 */
+	base = mmap(NULL, (size_t)symstrsize, PROT_READ, 0, fd,
+	    (off_t)symstroff);
+	if (base == MAP_FAILED)
+		goto done;
+	strtab = (char *)base;
+
+	/*
+	 * clean out any left-over information for all valid entries.
+	 * Type and value defined to be 0 if not found; historical
+	 * versions cleared other and desc as well.  Also figure out
+	 * the largest string length so don't read any more of the
+	 * string table than we have to.
+	 *
+	 * XXX clearing anything other than n_type and n_value violates
+	 * the semantics given in the man page.
+	 */
+	nent = 0;
+	for (p = list; !ISLAST(p); ++p) {
+		p->n_type = 0;
+		p->n_other = 0;
+		p->n_desc = 0;
+		p->n_value = 0;
+		++nent;
+	}
+
+	/* Don't process any further if object is stripped. */
+	if (symoff == 0)
+		goto done;
+		
+	if (lseek(fd, (off_t) symoff, SEEK_SET) == -1) {
+		nent = -1;
+		goto done;
+	}
+
+	while (symsize > 0 && nent > 0) {
+		cc = MIN(symsize, sizeof(sbuf));
+		if (read(fd, sbuf, cc) != cc)
+			break;
+		symsize -= cc;
+		for (s = sbuf; cc > 0 && nent > 0; ++s, cc -= sizeof(*s)) {
+			char *name;
+			struct nlist *p;
+
+			name = strtab + s->st_name;
+			if (name[0] == '\0')
+				continue;
+			for (p = list; !ISLAST(p); p++) {
+				if ((p->n_un.n_name[0] == '_' &&
+				    strcmp(name, p->n_un.n_name+1) == 0)
+				    || strcmp(name, p->n_un.n_name) == 0) {
+					elf_sym_to_nlist(p, s, shdr,
+					    ehdr.e_shnum);
+					if (--nent <= 0)
+						break;
+				}
+			}
+		}
+	}
+  done:
+	errsave = errno;
+	if (strtab != NULL)
+		munmap(strtab, symstrsize);
+	if (shdr != NULL)
+		munmap(shdr, shdr_size);
+	errno = errsave;
+	return (nent);
+}
+
+/*
+ * Convert an Elf_Sym into an nlist structure.  This fills in only the
+ * n_value and n_type members.
+ */
+static void
+elf_sym_to_nlist(nl, s, shdr, shnum)
+	struct nlist *nl;
+	Elf_Sym *s;
+	Elf_Shdr *shdr;
+	int shnum;
+{
+	nl->n_value = s->st_value;
+
+	switch (s->st_shndx) {
+	case SHN_UNDEF:
+	case SHN_COMMON:
+		nl->n_type = N_UNDF;
+		break;
+	case SHN_ABS:
+		nl->n_type = ELF_ST_TYPE(s->st_info) == STT_FILE ?
+		    N_FN : N_ABS;
+		break;
+	default:
+		if (s->st_shndx >= shnum)
+			nl->n_type = N_UNDF;
+		else {
+			Elf_Shdr *sh = shdr + s->st_shndx;
+
+			nl->n_type = sh->sh_type == SHT_PROGBITS ?
+			    (sh->sh_flags & SHF_WRITE ? N_DATA : N_TEXT) :
+			    (sh->sh_type == SHT_NOBITS ? N_BSS : N_UNDF);
+		}
+		break;
+	}
+
+	if (ELF_ST_BIND(s->st_info) == STB_GLOBAL ||
+	    ELF_ST_BIND(s->st_info) == STB_WEAK)
+		nl->n_type |= N_EXT;
+}
+#endif /* _NLIST_DO_ELF */
commit 8dbfb3529b0253ba8067042dabaebe3ad89cb039
Author: Guillem Jover <guillem at hadrons.org>
Date:   Fri May 15 21:40:45 2009 +0200

    Add strmode function

diff --git a/Makefile b/Makefile
index 904d21b..393a050 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 LIB_NAME := libbsd
 LIB_VERSION_MAJOR := 0
-LIB_VERSION_MINOR := 0
-LIB_VERSION_MICRO := 1
+LIB_VERSION_MINOR := 1
+LIB_VERSION_MICRO := 0
 LIB_VERSION := $(LIB_VERSION_MAJOR).$(LIB_VERSION_MINOR).$(LIB_VERSION_MICRO)
 
 LIB_PKGCONFIG := $(LIB_NAME).pc
@@ -30,6 +30,7 @@ LIB_SRCS := \
 	inet_net_pton.c \
 	hash/md5.c hash/md5hl.c \
 	setmode.c \
+	strmode.c \
 	strlcat.c strlcpy.c \
 	fmtcheck.c \
 	progname.c \
@@ -61,6 +62,7 @@ LIB_MANS := \
 	fgetln.3 \
 	fmtcheck.3 \
 	setmode.3 \
+	strmode.3 \
 	md5.3bsd
 LIB_MANS := $(patsubst %,man/%,$(LIB_MANS))
 
diff --git a/Versions b/Versions
index ba7606c..21123b6 100644
--- a/Versions
+++ b/Versions
@@ -34,3 +34,8 @@ LIBBSD_0.0 {
   local:
     *;
 };
+
+LIBBSD_0.1 {
+    strmode;
+} LIBBSD_0.0;
+
diff --git a/include/bsd/string.h b/include/bsd/string.h
index d19f7b3..185a42d 100644
--- a/include/bsd/string.h
+++ b/include/bsd/string.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005 Guillem Jover
+ * Copyright (C) 2004, 2005, 2009 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,4 +36,6 @@ size_t strlcat(char *dst, const char *src, size_t siz);
 char *fgetln(FILE *fp, size_t *lenp);
 wchar_t *fgetwln(FILE * __restrict fp, size_t *lenp);
 
+void strmode(mode_t mode, char *str);
+
 #endif
diff --git a/man/strmode.3 b/man/strmode.3
new file mode 100644
index 0000000..e119453
--- /dev/null
+++ b/man/strmode.3
@@ -0,0 +1,144 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY 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.
+.\"
+.\"     @(#)strmode.3	8.3 (Berkeley) 7/28/94
+.\" $FreeBSD: src/lib/libc/string/strmode.3,v 1.9 2003/07/01 15:28:05 maxim Exp $
+.\"
+.Dd July 28, 1994
+.Dt STRMODE 3
+.Os
+.Sh NAME
+.Nm strmode
+.Nd convert inode status information into a symbolic string
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In string.h
+.Ft void
+.Fn strmode "mode_t mode" "char *bp"
+.Sh DESCRIPTION
+The
+.Fn strmode
+function
+converts a file
+.Fa mode
+(the type and permission information associated with an inode, see
+.Xr stat 2 )
+into a symbolic string which is stored in the location referenced by
+.Fa bp .
+This stored string is eleven characters in length plus a trailing
+.Dv NUL .
+.Pp
+The first character is the inode type, and will be one of the following:
+.Pp
+.Bl -tag -width flag -offset indent -compact
+.It \-
+regular file
+.It b
+block special
+.It c
+character special
+.It d
+directory
+.It l
+symbolic link
+.It p
+fifo
+.It s
+socket
+.It w
+whiteout
+.It ?
+unknown inode type
+.El
+.Pp
+The next nine characters encode three sets of permissions, in three
+characters each.
+The first three characters are the permissions for the owner of the
+file, the second three for the group the file belongs to, and the
+third for the ``other'', or default, set of users.
+.Pp
+Permission checking is done as specifically as possible.
+If read permission is denied to the owner of a file in the first set
+of permissions, the owner of the file will not be able to read the file.
+This is true even if the owner is in the file's group and the group
+permissions allow reading or the ``other'' permissions allow reading.
+.Pp
+If the first character of the three character set is an ``r'', the file is
+readable for that set of users; if a dash ``\-'', it is not readable.
+.Pp
+If the second character of the three character set is a ``w'', the file is
+writable for that set of users; if a dash ``\-'', it is not writable.
+.Pp
+The third character is the first of the following characters that apply:
+.Bl -tag -width xxxx
+.It S
+If the character is part of the owner permissions and the file is not
+executable or the directory is not searchable by the owner, and the
+set-user-id bit is set.
+.It S
+If the character is part of the group permissions and the file is not
+executable or the directory is not searchable by the group, and the
+set-group-id bit is set.
+.It T
+If the character is part of the other permissions and the file is not
+executable or the directory is not searchable by others, and the ``sticky''
+.Pq Dv S_ISVTX
+bit is set.
+.It s
+If the character is part of the owner permissions and the file is
+executable or the directory searchable by the owner, and the set-user-id
+bit is set.
+.It s
+If the character is part of the group permissions and the file is
+executable or the directory searchable by the group, and the set-group-id
+bit is set.
+.It t
+If the character is part of the other permissions and the file is
+executable or the directory searchable by others, and the ``sticky''
+.Pq Dv S_ISVTX
+bit is set.
+.It x
+The file is executable or the directory is searchable.
+.It \-
+None of the above apply.
+.El
+.Pp
+The last character is a plus sign ``+'' if any there are any alternate
+or additional access control methods associated with the inode, otherwise
+it will be a space.
+.Sh SEE ALSO
+.Xr chmod 1 ,
+.Xr find 1 ,
+.Xr stat 2 ,
+.Xr getmode 3 ,
+.Xr setmode 3
+.Sh HISTORY
+The
+.Fn strmode
+function first appeared in
+.Bx 4.4 .
diff --git a/src/strmode.c b/src/strmode.c
new file mode 100644
index 0000000..97136e6
--- /dev/null
+++ b/src/strmode.c
@@ -0,0 +1,149 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strmode.c	8.3 (Berkeley) 8/15/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+void
+strmode(mode, p)
+	mode_t mode;
+	char *p;
+{
+	 /* print type */
+	switch (mode & S_IFMT) {
+	case S_IFDIR:			/* directory */
+		*p++ = 'd';
+		break;
+	case S_IFCHR:			/* character special */
+		*p++ = 'c';
+		break;
+	case S_IFBLK:			/* block special */
+		*p++ = 'b';
+		break;
+	case S_IFREG:			/* regular */
+		*p++ = '-';
+		break;
+	case S_IFLNK:			/* symbolic link */
+		*p++ = 'l';
+		break;
+	case S_IFSOCK:			/* socket */
+		*p++ = 's';
+		break;
+#ifdef S_IFIFO
+	case S_IFIFO:			/* fifo */
+		*p++ = 'p';
+		break;
+#endif
+#ifdef S_IFWHT
+	case S_IFWHT:			/* whiteout */
+		*p++ = 'w';
+		break;
+#endif
+	default:			/* unknown */
+		*p++ = '?';
+		break;
+	}
+	/* usr */
+	if (mode & S_IRUSR)
+		*p++ = 'r';
+	else
+		*p++ = '-';
+	if (mode & S_IWUSR)
+		*p++ = 'w';
+	else
+		*p++ = '-';
+	switch (mode & (S_IXUSR | S_ISUID)) {
+	case 0:
+		*p++ = '-';
+		break;
+	case S_IXUSR:
+		*p++ = 'x';
+		break;
+	case S_ISUID:
+		*p++ = 'S';
+		break;
+	case S_IXUSR | S_ISUID:
+		*p++ = 's';
+		break;
+	}
+	/* group */
+	if (mode & S_IRGRP)
+		*p++ = 'r';
+	else
+		*p++ = '-';
+	if (mode & S_IWGRP)
+		*p++ = 'w';
+	else
+		*p++ = '-';
+	switch (mode & (S_IXGRP | S_ISGID)) {
+	case 0:
+		*p++ = '-';
+		break;
+	case S_IXGRP:
+		*p++ = 'x';
+		break;
+	case S_ISGID:
+		*p++ = 'S';
+		break;
+	case S_IXGRP | S_ISGID:
+		*p++ = 's';
+		break;
+	}
+	/* other */
+	if (mode & S_IROTH)
+		*p++ = 'r';
+	else
+		*p++ = '-';
+	if (mode & S_IWOTH)
+		*p++ = 'w';
+	else
+		*p++ = '-';
+	switch (mode & (S_IXOTH | S_ISVTX)) {
+	case 0:
+		*p++ = '-';
+		break;
+	case S_IXOTH:
+		*p++ = 'x';
+		break;
+	case S_ISVTX:
+		*p++ = 'T';
+		break;
+	case S_IXOTH | S_ISVTX:
+		*p++ = 't';
+		break;
+	}
+	*p++ = ' ';		/* will be a '+' if ACL's implemented */
+	*p = '\0';
+}
commit 74ae34e792a08de78ab671a683abdf48c27eccd3
Author: Guillem Jover <guillem at hadrons.org>
Date:   Fri May 15 21:26:09 2009 +0200

    Fix buffer leaks in fgetln
    
    Cache the size and the buffer allocated by getline as static variables.

diff --git a/src/fgetln.c b/src/fgetln.c
index 2e6eac9..33b261b 100644
--- a/src/fgetln.c
+++ b/src/fgetln.c
@@ -34,8 +34,8 @@
 char *
 fgetln (FILE *stream, size_t *len)
 {
-	char *line = NULL;
-	size_t line_len = 0;
+	static char *line = NULL;
+	static size_t line_len = 0;
 	ssize_t nread;
 
 	nread = getline(&line, &line_len, stream);
commit deb9f56ceb560f96448ff9bfa1befdf7ed9849de
Author: Guillem Jover <guillem at hadrons.org>
Date:   Fri May 15 21:23:03 2009 +0200

    Change fgetln to return the correct length value
    
    Set len to 0 on error conditions to mimmic FreeBSD behaviour, and return
    the amount of read characters on success, instead of the allocated size
    by getline.
    
    Reported-by: Jief L. <jief1.l at gmail.com>

diff --git a/src/fgetln.c b/src/fgetln.c
index e59028b..2e6eac9 100644
--- a/src/fgetln.c
+++ b/src/fgetln.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2005 Hector Garcia Alvarez
- * Copyright (C) 2005, 2008 Guillem Jover
+ * Copyright (C) 2005, 2008, 2009 Guillem Jover
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,16 +35,17 @@ char *
 fgetln (FILE *stream, size_t *len)
 {
 	char *line = NULL;
+	size_t line_len = 0;
 	ssize_t nread;
 
-	nread = getline (&line, len, stream);
-	if (nread == -1)
+	nread = getline(&line, &line_len, stream);
+	if (nread == -1) {
+		*len = 0;
 		return NULL;
-
-	/* Get rid of the trailing \0, fgetln does not have it. */
-	(*len)--;
-
-	return line;
+	} else {
+		*len = (size_t)nread;
+		return line;
+	}
 }
 #endif
 


More information about the libbsd mailing list