summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc/port/gen/deflt.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libc/port/gen/deflt.c')
-rw-r--r--usr/src/lib/libc/port/gen/deflt.c140
1 files changed, 125 insertions, 15 deletions
diff --git a/usr/src/lib/libc/port/gen/deflt.c b/usr/src/lib/libc/port/gen/deflt.c
index 716b3dd79e..72a0f8862a 100644
--- a/usr/src/lib/libc/port/gen/deflt.c
+++ b/usr/src/lib/libc/port/gen/deflt.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,8 +30,6 @@
/* Copyright (c) 1987, 1988 Microsoft Corporation */
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "lint.h"
#include "libc.h"
#include <stdio.h>
@@ -45,14 +43,15 @@
#define TSTBITS(flags, mask) (((flags) & (mask)) == (mask))
-static void strip_quotes(char *);
-
struct thr_data {
int Dcflags; /* [re-]initialized on each call to defopen() */
FILE *fp;
char *buf;
};
+static int defopen_common(const char *, struct thr_data *);
+static void strip_quotes(char *);
+
#define BUFFERSIZE 1024
/*
@@ -105,6 +104,46 @@ defopen(char *fn)
{
struct thr_data *thr_data = get_thr_data();
+ return (defopen_common(fn, thr_data));
+}
+
+/*
+ * defopen_r() - declare defopen filename (reentrant)
+ *
+ * defopen_r(const char *fn)
+ *
+ * 'fn' is a full pathname of a file which becomes the one read
+ * by subsequent defread_r() calls. defopen_r returns a pointer
+ * to the internally allocated buffer containing the file descriptor.
+ * The pointer should be specified to the following defread_r and
+ * defcntl_r functions. As the pointer to be returned points to
+ * the libc lmalloc'd memory, defclose_r must be used to close
+ * the defopen file and to release the allocated memory. Caller
+ * must not try to release the memory by free().
+ *
+ * see defread_r() for more details.
+ *
+ * EXIT returns non-NULL pointer if success
+ * returns NULL if error
+ */
+void *
+defopen_r(const char *fn)
+{
+ /* memory allocated by lmalloc gets initialized to zeros */
+ struct thr_data *thr_data = lmalloc(sizeof (struct thr_data));
+
+ if (defopen_common(fn, thr_data) < 0) {
+ if (thr_data != NULL)
+ lfree(thr_data, sizeof (struct thr_data));
+ return (NULL);
+ }
+
+ return ((void *)thr_data);
+}
+
+static int
+defopen_common(const char *fn, struct thr_data *thr_data)
+{
if (thr_data == NULL)
return (-1);
@@ -121,7 +160,8 @@ defopen(char *fn)
/*
* We allocate the big buffer only if the fopen() succeeds.
- * Notice that we deallocate the buffer only when the thread exits.
+ * Notice that we deallocate the buffer only when the thread exits
+ * for defopen().
* There are misguided applications that assume that data returned
* by defread() continues to exist after defopen(NULL) is called.
*/
@@ -150,7 +190,7 @@ defopen(char *fn)
* the matched string (*cp). If no line is found or no file
* is open, defread() returns NULL.
*
- * Note that there is no way to simulatniously peruse multiple
+ * Note that there is no way to simultaneously peruse multiple
* defopen files; since there is no way of indicating 'which one'
* to defread(). If you want to peruse a secondary file you must
* recall defopen(). If you need to go back to the first file,
@@ -160,8 +200,29 @@ char *
defread(char *cp)
{
struct thr_data *thr_data = get_thr_data();
+
+ return (defread_r(cp, thr_data));
+}
+
+/*
+ * defread_r() - read an entry from the defopen file
+ *
+ * defread_r(const char *cp, void *defp)
+ *
+ * defread_r scans the data file associated with the pointer
+ * specified by 'defp' that was returned by defopen_r(), and
+ * looks for a line which begins with the string '*cp'.
+ * If such a line is found, defread_r returns a pointer to
+ * the first character following the matched string (*cp).
+ * If no line is found or no file is open, defread_r() returns NULL.
+ */
+char *
+defread_r(const char *cp, void *ptr)
+{
+ struct thr_data *thr_data = (struct thr_data *)ptr;
int (*compare)(const char *, const char *, size_t);
- char *buf_tmp, *ret_ptr = NULL;
+ char *buf_tmp;
+ char *ret_ptr = NULL;
size_t off, patlen;
if (thr_data == NULL || thr_data->fp == NULL)
@@ -203,21 +264,52 @@ defread(char *cp)
*
* ENTRY
* cmd Command. One of DC_GET, DC_SET.
- * arg Depends on command. If DC_GET, ignored. If
- * DC_GET, new flags value, created by ORing the DC_* bits.
+ * arg Depends on command. If DC_GET, ignored.
+ * If DC_SET, new flags value, created by ORing
+ * the DC_* bits.
* RETURN
* oldflags Old value of flags. -1 on error.
* NOTES
- * Currently only one bit of flags implemented, namely respect/
- * ignore case. The routine is as general as it is so that we
- * leave our options open. E.g. we might want to specify rewind/
- * norewind before each defread.
+ * The following commands are implemented:
+ *
+ * DC_CASE: respect(on)/ignore(off) case
+ * DC_NOREWIND: don't(on)/do(off) reqind in defread
+ * DC_STRIP_QUOTES: strip(on)/leave(off) qoates
*/
-
int
defcntl(int cmd, int newflags)
{
struct thr_data *thr_data = get_thr_data();
+
+ return (defcntl_r(cmd, newflags, thr_data));
+}
+
+/*
+ * defcntl_r -- default control
+ *
+ * SYNOPSIS
+ * oldflags = defcntl_r(int cmd, int arg, void *defp);
+ *
+ * ENTRY
+ * cmd Command. One of DC_GET, DC_SET.
+ * arg Depends on command. If DC_GET, ignored.
+ * If DC_SET, new flags value, created by ORing
+ * the DC_* bits.
+ * defp pointer to the defopen'd descriptor
+ *
+ * RETURN
+ * oldflags Old value of flags. -1 on error.
+ * NOTES
+ * The following commands are implemented:
+ *
+ * DC_CASE: respect(on)/ignore(off) case
+ * DC_NOREWIND: don't(on)/do(off) reqind in defread
+ * DC_STRIP_QUOTES: strip(on)/leave(off) qoates
+ */
+int
+defcntl_r(int cmd, int newflags, void *ptr)
+{
+ struct thr_data *thr_data = (struct thr_data *)ptr;
int oldflags;
if (thr_data == NULL)
@@ -240,6 +332,24 @@ defcntl(int cmd, int newflags)
}
/*
+ * defclose_r() - close defopen file
+ *
+ * defclose_r(void *defp)
+ *
+ * defclose_r closes the defopen file associated with the specified
+ * pointer and releases the allocated resources.
+ */
+void
+defclose_r(void *ptr)
+{
+ struct thr_data *thr_data = (struct thr_data *)ptr;
+
+ (void) fclose(thr_data->fp);
+ lfree(thr_data->buf, BUFFERSIZE);
+ lfree(thr_data, sizeof (struct thr_data));
+}
+
+/*
* strip_quotes -- strip double (") or single (') quotes from a buffer
*
* ENTRY