1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1999,2008 Oracle.  All rights reserved.
5 *
6 * $Id: os_errno.c,v 1.6 2008/01/08 20:58:44 bostic Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13/*
14 * __os_get_errno_ret_zero --
15 *	Return the last system error, including an error of zero.
16 */
17int
18__os_get_errno_ret_zero()
19{
20	/* This routine must be able to return the same value repeatedly. */
21	return (errno);
22}
23
24/*
25 * We've seen cases where system calls failed but errno was never set.  For
26 * that reason, __os_get_errno() and __os_get_syserr set errno to EAGAIN if
27 * it's not already set, to work around the problem.  For obvious reasons,
28 * we can only call this function if we know an error has occurred, that
29 * is, we can't test the return for a non-zero value after the get call.
30 *
31 * __os_get_errno --
32 *	Return the last ANSI C "errno" value or EAGAIN if the last error
33 *	is zero.
34 */
35int
36__os_get_errno()
37{
38	/* This routine must be able to return the same value repeatedly. */
39	if (errno == 0)
40		__os_set_errno(EAGAIN);
41	return (errno);
42}
43
44/*
45 * __os_get_syserr --
46 *	Return the last system error or EAGAIN if the last error is zero.
47 */
48int
49__os_get_syserr()
50{
51	/* This routine must be able to return the same value repeatedly. */
52	if (errno == 0)
53		__os_set_errno(EAGAIN);
54	return (errno);
55}
56
57/*
58 * __os_set_errno --
59 *	Set the value of errno.
60 */
61void
62__os_set_errno(evalue)
63	int evalue;
64{
65	/*
66	 * This routine is called by the compatibility interfaces (DB 1.85,
67	 * dbm and hsearch).  Force values > 0, that is, not one of DB 2.X
68	 * and later's public error returns.  If something bad has happened,
69	 * default to EFAULT -- a nasty return.  Otherwise, default to EINVAL.
70	 * As the compatibility APIs aren't included on Windows, the Windows
71	 * version of this routine doesn't need this behavior.
72	 */
73	errno =
74	    evalue >= 0 ? evalue : (evalue == DB_RUNRECOVERY ? EFAULT : EINVAL);
75}
76
77/*
78 * __os_strerror --
79 *	Return a string associated with the system error.
80 */
81char *
82__os_strerror(error, buf, len)
83	int error;
84	char *buf;
85	size_t len;
86{
87	char *p;
88
89	switch (error) {
90	case EBADFILENAME:
91		p = "EBADFILENAME";
92		break;
93	case EBADSEEKPOS:
94		p = "EBADSEEKPOS";
95		break;
96#ifndef HAVE_BREW_SDK2
97	case EDIRNOEXISTS:
98		p = "EDIRNOEXISTS";
99		break;
100#endif
101	case EDIRNOTEMPTY:
102		p = "EDIRNOTEMPTY";
103		break;
104	case EFILEEOF:
105		p = "EFILEEOF";
106		break;
107	case EFILEEXISTS:
108		p = "EFILEEXISTS";
109		break;
110	case EFILENOEXISTS:
111		p = "EFILENOEXISTS";
112		break;
113	case EFILEOPEN:
114		p = "EFILEOPEN";
115		break;
116	case EFSFULL:
117		p = "EFSFULL";
118		break;
119#ifndef HAVE_BREW_SDK2
120	case EINVALIDOPERATION:
121		p = "EINVALIDOPERATION";
122		break;
123	case ENOMEDIA:
124		p = "ENOMEDIA";
125		break;
126#endif
127	case ENOMEMORY:
128		p = "ENOMEMORY";
129		break;
130	case EOUTOFNODES:
131		p = "EOUTOFNODES";
132		break;
133	default:
134		p = __db_unknown_error(error);
135		break;
136	}
137
138	(void)strncpy(buf, p, len - 1);
139	buf[len - 1] = '\0';
140
141	return (buf);
142}
143
144/*
145 * __os_posix_err
146 *	Convert a system error to a POSIX error.
147 */
148int
149__os_posix_err(error)
150	int error;
151{
152	int ret;
153
154	switch (error) {
155	case EBADFILENAME:
156#ifndef HAVE_BREW_SDK2
157	case EDIRNOEXISTS:
158#endif
159	case EDIRNOTEMPTY:
160	case EFILENOEXISTS:
161		ret = ENOENT;
162		break;
163
164	case EOUTOFNODES:
165		ret = EMFILE;
166		break;
167
168	case ENOMEMORY:
169		ret = ENOMEM;
170		break;
171
172	case EFSFULL:
173		ret = ENOSPC;
174		break;
175
176#ifndef HAVE_BREW_SDK2
177	case EINVALIDOPERATION:
178		ret = DB_OPNOTSUP;
179		break;
180#endif
181
182	case EFILEEXISTS:
183		ret = EEXIST;
184		break;
185
186	case EBADSEEKPOS:
187	case EFILEEOF:
188		ret = EIO;
189		break;
190
191	default:
192		ret = EFAULT;
193		break;
194	}
195	return (ret);
196}
197