Change everything to store error code through provided pointer and not
[kopensolaris-gnu/glibc.git] / nss / nss_db / db-XXX.c
index 0c41761..4d20cae 100644 (file)
@@ -1,25 +1,25 @@
 /* Common code for DB-based databases in nss_db module.
-Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
-#include <db.h>
+#include <db_185.h>
 #include <fcntl.h>
-#include <libc-lock.h>
+#include <bits/libc-lock.h>
 #include "nsswitch.h"
 
 /* These symbols are defined by the including source file:
@@ -63,10 +63,30 @@ internal_setent (int stayopen)
 
   if (db == NULL)
     {
-      db = dbopen (DBFILE, O_RDONLY, 0, DB_BTREE, NULL);
+      db = __dbopen (DBFILE, O_RDONLY, 0, DB_BTREE, NULL);
 
       if (db == NULL)
-       status = NSS_STATUS_UNAVAIL;
+       status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+      else
+       {
+         /* We have to make sure the file is  `closed on exec'.  */
+         int result, flags;
+
+         result = flags = fcntl ((*db->fd) (db), F_GETFD, 0);
+         if (result >= 0)
+           {
+             flags |= FD_CLOEXEC;
+             result = fcntl ((*db->fd) (db), F_SETFD, flags);
+           }
+         if (result < 0)
+           {
+             /* Something went wrong.  Close the stream and return a
+                failure.  */
+             (*db->close) (db);
+             db = NULL;
+             status = NSS_STATUS_UNAVAIL;
+           }
+       }
     }
 
   /* Remember STAYOPEN flag.  */
@@ -127,9 +147,10 @@ CONCAT(_nss_db_end,ENTNAME) (void)
 /* Do a database lookup for KEY.  */
 static enum nss_status
 lookup (const DBT *key, struct STRUCTURE *result,
-       void *buffer, int buflen H_ERRNO_PROTO)
+       void *buffer, size_t buflen, int *errnop H_ERRNO_PROTO)
 {
   enum nss_status status;
+  int err;
   DBT value;
 
   /* Open the database.  */
@@ -138,9 +159,12 @@ lookup (const DBT *key, struct STRUCTURE *result,
     return status;
 
   /* Succeed iff it matches a value that parses correctly.  */
-  status = (((*db->get) (db, key, &value, 0) == 0 &&
-            parse_line (value.data, result, buffer, buflen))
-           ? NSS_STATUS_SUCCESS : NSS_STATUS_NOTFOUND);
+  err = ((*db->get) (db, key, &value, 0) == 0 &&
+        parse_line (value.data, result, buffer, buflen, errnop));
+  if (err == 0)
+    status = NSS_STATUS_SUCCESS;
+  else
+    status = err < 0 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
 
   if (! keep_db)
     internal_endent ();
@@ -168,7 +192,7 @@ lookup (const DBT *key, struct STRUCTURE *result,
 enum nss_status                                                                      \
 _nss_db_get##name##_r (proto,                                                \
                       struct STRUCTURE *result,                              \
-                      char *buffer, int buflen H_ERRNO_PROTO)                \
+                      char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO)\
 {                                                                            \
   DBT key;                                                                   \
   enum nss_status status;                                                    \
@@ -176,7 +200,7 @@ _nss_db_get##name##_r (proto,                                                     \
   key.data = __alloca (size);                                                \
   key.size = KEYPRINTF keypattern;                                           \
   __libc_lock_lock (lock);                                                   \
-  status = lookup (&key, result, buffer, buflen H_ERRNO_ARG);                \
+  status = lookup (&key, result, buffer, buflen, errnop H_ERRNO_ARG);        \
   __libc_lock_unlock (lock);                                                 \
   return status;                                                             \
 }
@@ -188,8 +212,8 @@ _nss_db_get##name##_r (proto,                                                     \
 
 /* Return the next entry from the database file, doing locking.  */
 enum nss_status
-CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result,
-                              char *buffer, int buflen H_ERRNO_PROTO)
+CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
+                              size_t buflen, int *errnop H_ERRNO_PROTO)
 {
   /* Return next entry in host file.  */
   enum nss_status status;
@@ -198,7 +222,7 @@ CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result,
 
   __libc_lock_lock (lock);
   key.size = 1 + snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
-  status = lookup (&key, result, buffer, buflen H_ERRNO_ARG);
+  status = lookup (&key, result, buffer, buflen, errnop H_ERRNO_ARG);
   __libc_lock_unlock (lock);
 
   return status;