Brad Bishop | bba38f3 | 2018-08-23 16:11:46 +0800 | [diff] [blame] | 1 | From 6b638fa9afbeb54dfa19378e391465a5284ce1ad Mon Sep 17 00:00:00 2001 |
| 2 | From: Changqing Li <changqing.li@windriver.com> |
| 3 | Date: Wed, 12 Sep 2018 17:16:36 +0800 |
| 4 | Subject: [PATCH] Fix error handling in gdbm |
| 5 | |
| 6 | Only check for gdbm_errno if the return value of the called gdbm_* |
| 7 | function says so. This fixes apr-util with gdbm 1.14, which does not |
| 8 | seem to always reset gdbm_errno. |
| 9 | |
| 10 | Also make the gdbm driver return error codes starting with |
| 11 | APR_OS_START_USEERR instead of always returning APR_EGENERAL. This is |
| 12 | what the berkleydb driver already does. |
| 13 | |
| 14 | Also ensure that dsize is 0 if dptr == NULL. |
| 15 | |
Andrew Geissler | 595f630 | 2022-01-24 19:11:47 +0000 | [diff] [blame] | 16 | Upstream-Status: Backport [https://svn.apache.org/viewvc?view=revision&revision=1825311] |
Brad Bishop | bba38f3 | 2018-08-23 16:11:46 +0800 | [diff] [blame] | 17 | |
| 18 | Signed-off-by: Changqing Li <changqing.li@windriver.com> |
| 19 | --- |
| 20 | dbm/apr_dbm_gdbm.c | 47 +++++++++++++++++++++++++++++------------------ |
| 21 | 1 file changed, 29 insertions(+), 18 deletions(-) |
| 22 | |
| 23 | diff --git a/dbm/apr_dbm_gdbm.c b/dbm/apr_dbm_gdbm.c |
| 24 | index 749447a..1c86327 100644 |
| 25 | --- a/dbm/apr_dbm_gdbm.c |
| 26 | +++ b/dbm/apr_dbm_gdbm.c |
| 27 | @@ -36,13 +36,25 @@ |
| 28 | static apr_status_t g2s(int gerr) |
| 29 | { |
| 30 | if (gerr == -1) { |
| 31 | - /* ### need to fix this */ |
| 32 | - return APR_EGENERAL; |
| 33 | + if (gdbm_errno == GDBM_NO_ERROR) |
| 34 | + return APR_SUCCESS; |
| 35 | + return APR_OS_START_USEERR + gdbm_errno; |
| 36 | } |
| 37 | |
| 38 | return APR_SUCCESS; |
| 39 | } |
| 40 | |
| 41 | +static apr_status_t gdat2s(datum d) |
| 42 | +{ |
| 43 | + if (d.dptr == NULL) { |
| 44 | + if (gdbm_errno == GDBM_NO_ERROR || gdbm_errno == GDBM_ITEM_NOT_FOUND) |
| 45 | + return APR_SUCCESS; |
| 46 | + return APR_OS_START_USEERR + gdbm_errno; |
| 47 | + } |
| 48 | + |
| 49 | + return APR_SUCCESS; |
| 50 | +} |
| 51 | + |
| 52 | static apr_status_t datum_cleanup(void *dptr) |
| 53 | { |
| 54 | if (dptr) |
| 55 | @@ -53,22 +65,15 @@ static apr_status_t datum_cleanup(void *dptr) |
| 56 | |
| 57 | static apr_status_t set_error(apr_dbm_t *dbm, apr_status_t dbm_said) |
| 58 | { |
| 59 | - apr_status_t rv = APR_SUCCESS; |
| 60 | |
| 61 | - /* ### ignore whatever the DBM said (dbm_said); ask it explicitly */ |
| 62 | + dbm->errcode = dbm_said; |
| 63 | |
| 64 | - if ((dbm->errcode = gdbm_errno) == GDBM_NO_ERROR) { |
| 65 | + if (dbm_said == APR_SUCCESS) |
| 66 | dbm->errmsg = NULL; |
| 67 | - } |
| 68 | - else { |
| 69 | - dbm->errmsg = gdbm_strerror(gdbm_errno); |
| 70 | - rv = APR_EGENERAL; /* ### need something better */ |
| 71 | - } |
| 72 | - |
| 73 | - /* captured it. clear it now. */ |
| 74 | - gdbm_errno = GDBM_NO_ERROR; |
| 75 | + else |
| 76 | + dbm->errmsg = gdbm_strerror(dbm_said - APR_OS_START_USEERR); |
| 77 | |
| 78 | - return rv; |
| 79 | + return dbm_said; |
| 80 | } |
| 81 | |
| 82 | /* -------------------------------------------------------------------------- |
| 83 | @@ -107,7 +112,7 @@ static apr_status_t vt_gdbm_open(apr_dbm_t **pdb, const char *pathname, |
| 84 | NULL); |
| 85 | |
| 86 | if (file == NULL) |
| 87 | - return APR_EGENERAL; /* ### need a better error */ |
| 88 | + return APR_OS_START_USEERR + gdbm_errno; /* ### need a better error */ |
| 89 | |
| 90 | /* we have an open database... return it */ |
| 91 | *pdb = apr_pcalloc(pool, sizeof(**pdb)); |
| 92 | @@ -141,10 +146,12 @@ static apr_status_t vt_gdbm_fetch(apr_dbm_t *dbm, apr_datum_t key, |
| 93 | if (pvalue->dptr) |
| 94 | apr_pool_cleanup_register(dbm->pool, pvalue->dptr, datum_cleanup, |
| 95 | apr_pool_cleanup_null); |
| 96 | + else |
| 97 | + pvalue->dsize = 0; |
| 98 | |
| 99 | /* store the error info into DBM, and return a status code. Also, note |
| 100 | that *pvalue should have been cleared on error. */ |
| 101 | - return set_error(dbm, APR_SUCCESS); |
| 102 | + return set_error(dbm, gdat2s(rd)); |
| 103 | } |
| 104 | |
| 105 | static apr_status_t vt_gdbm_store(apr_dbm_t *dbm, apr_datum_t key, |
| 106 | @@ -201,9 +208,11 @@ static apr_status_t vt_gdbm_firstkey(apr_dbm_t *dbm, apr_datum_t *pkey) |
| 107 | if (pkey->dptr) |
| 108 | apr_pool_cleanup_register(dbm->pool, pkey->dptr, datum_cleanup, |
| 109 | apr_pool_cleanup_null); |
| 110 | + else |
| 111 | + pkey->dsize = 0; |
| 112 | |
| 113 | /* store any error info into DBM, and return a status code. */ |
| 114 | - return set_error(dbm, APR_SUCCESS); |
| 115 | + return set_error(dbm, gdat2s(rd)); |
| 116 | } |
| 117 | |
| 118 | static apr_status_t vt_gdbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey) |
| 119 | @@ -221,9 +230,11 @@ static apr_status_t vt_gdbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey) |
| 120 | if (pkey->dptr) |
| 121 | apr_pool_cleanup_register(dbm->pool, pkey->dptr, datum_cleanup, |
| 122 | apr_pool_cleanup_null); |
| 123 | + else |
| 124 | + pkey->dsize = 0; |
| 125 | |
| 126 | /* store any error info into DBM, and return a status code. */ |
| 127 | - return set_error(dbm, APR_SUCCESS); |
| 128 | + return set_error(dbm, gdat2s(rd)); |
| 129 | } |
| 130 | |
| 131 | static void vt_gdbm_freedatum(apr_dbm_t *dbm, apr_datum_t data) |
| 132 | -- |
| 133 | 2.7.4 |
| 134 | |