Coverage Report

Created: 2026-07-16 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5Plapl.c
Line
Count
Source
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*-------------------------------------------------------------------------
14
 *
15
 * Created:   H5Plapl.c
16
 *
17
 * Purpose:   Link access property list class routines
18
 *
19
 *-------------------------------------------------------------------------
20
 */
21
22
/****************/
23
/* Module Setup */
24
/****************/
25
26
#include "H5Pmodule.h" /* This source code file is part of the H5P module */
27
28
/***********/
29
/* Headers */
30
/***********/
31
#include "H5private.h"   /* Generic Functions                        */
32
#include "H5Eprivate.h"  /* Error handling                           */
33
#include "H5Iprivate.h"  /* IDs                                      */
34
#include "H5Lprivate.h"  /* Links                                    */
35
#include "H5MMprivate.h" /* Memory management                        */
36
#include "H5Ppkg.h"      /* Property lists                           */
37
#include "H5VMprivate.h" /* Vector Functions                         */
38
39
/****************/
40
/* Local Macros */
41
/****************/
42
43
/* ========  Link access properties ======== */
44
/* Definitions for number of soft links to traverse */
45
2
#define H5L_ACS_NLINKS_SIZE sizeof(size_t)
46
#define H5L_ACS_NLINKS_DEF  H5L_NUM_LINKS /*max symlinks to follow per lookup  */
47
2
#define H5L_ACS_NLINKS_ENC  H5P__encode_size_t
48
2
#define H5L_ACS_NLINKS_DEC  H5P__decode_size_t
49
50
/* Definitions for external link prefix */
51
2
#define H5L_ACS_ELINK_PREFIX_SIZE  sizeof(char *)
52
#define H5L_ACS_ELINK_PREFIX_DEF   NULL /*default is no prefix */
53
2
#define H5L_ACS_ELINK_PREFIX_SET   H5P__lacc_elink_pref_set
54
2
#define H5L_ACS_ELINK_PREFIX_GET   H5P__lacc_elink_pref_get
55
2
#define H5L_ACS_ELINK_PREFIX_ENC   H5P__lacc_elink_pref_enc
56
2
#define H5L_ACS_ELINK_PREFIX_DEC   H5P__lacc_elink_pref_dec
57
2
#define H5L_ACS_ELINK_PREFIX_DEL   H5P__lacc_elink_pref_del
58
2
#define H5L_ACS_ELINK_PREFIX_COPY  H5P__lacc_elink_pref_copy
59
2
#define H5L_ACS_ELINK_PREFIX_CMP   H5P__lacc_elink_pref_cmp
60
2
#define H5L_ACS_ELINK_PREFIX_CLOSE H5P__lacc_elink_pref_close
61
62
/* Definitions for setting fapl of external link access */
63
2
#define H5L_ACS_ELINK_FAPL_SIZE  sizeof(hid_t)
64
#define H5L_ACS_ELINK_FAPL_DEF   H5P_DEFAULT
65
2
#define H5L_ACS_ELINK_FAPL_SET   H5P__lacc_elink_fapl_set
66
2
#define H5L_ACS_ELINK_FAPL_GET   H5P__lacc_elink_fapl_get
67
2
#define H5L_ACS_ELINK_FAPL_ENC   H5P__lacc_elink_fapl_enc
68
2
#define H5L_ACS_ELINK_FAPL_DEC   H5P__lacc_elink_fapl_dec
69
2
#define H5L_ACS_ELINK_FAPL_DEL   H5P__lacc_elink_fapl_del
70
2
#define H5L_ACS_ELINK_FAPL_COPY  H5P__lacc_elink_fapl_copy
71
2
#define H5L_ACS_ELINK_FAPL_CMP   H5P__lacc_elink_fapl_cmp
72
2
#define H5L_ACS_ELINK_FAPL_CLOSE H5P__lacc_elink_fapl_close
73
74
/* Definitions for file access flags for external link traversal */
75
2
#define H5L_ACS_ELINK_FLAGS_SIZE sizeof(unsigned)
76
#define H5L_ACS_ELINK_FLAGS_DEF  H5F_ACC_DEFAULT
77
2
#define H5L_ACS_ELINK_FLAGS_ENC  H5P__encode_unsigned
78
2
#define H5L_ACS_ELINK_FLAGS_DEC  H5P__decode_unsigned
79
80
/* Definitions for callback function for external link traversal */
81
2
#define H5L_ACS_ELINK_CB_SIZE sizeof(H5L_elink_cb_t)
82
#define H5L_ACS_ELINK_CB_DEF                                                                                 \
83
    {                                                                                                        \
84
        NULL, NULL                                                                                           \
85
    }
86
87
#ifdef H5_HAVE_PARALLEL
88
/* Definition for reading metadata collectively */
89
#define H5L_ACS_COLL_MD_READ_SIZE sizeof(H5P_coll_md_read_flag_t)
90
#define H5L_ACS_COLL_MD_READ_DEF  H5P_USER_FALSE
91
#define H5L_ACS_COLL_MD_READ_ENC  H5P__encode_coll_md_read_flag_t
92
#define H5L_ACS_COLL_MD_READ_DEC  H5P__decode_coll_md_read_flag_t
93
#endif /* H5_HAVE_PARALLEL */
94
95
/******************/
96
/* Local Typedefs */
97
/******************/
98
99
/********************/
100
/* Package Typedefs */
101
/********************/
102
103
/********************/
104
/* Local Prototypes */
105
/********************/
106
107
/* Property class callbacks */
108
static herr_t H5P__lacc_reg_prop(H5P_genclass_t *pclass);
109
110
/* Property list callbacks */
111
static herr_t H5P__lacc_elink_pref_set(hid_t prop_id, const char *name, size_t size, void *value);
112
static herr_t H5P__lacc_elink_pref_get(hid_t prop_id, const char *name, size_t size, void *value);
113
static herr_t H5P__lacc_elink_pref_enc(const void *value, void **_pp, size_t *size);
114
static herr_t H5P__lacc_elink_pref_dec(const void **_pp, void *value);
115
static herr_t H5P__lacc_elink_pref_del(hid_t prop_id, const char *name, size_t size, void *value);
116
static herr_t H5P__lacc_elink_pref_copy(const char *name, size_t size, void *value);
117
static int    H5P__lacc_elink_pref_cmp(const void *value1, const void *value2, size_t size);
118
static herr_t H5P__lacc_elink_pref_close(const char *name, size_t size, void *value);
119
static herr_t H5P__lacc_elink_fapl_set(hid_t prop_id, const char *name, size_t size, void *value);
120
static herr_t H5P__lacc_elink_fapl_get(hid_t prop_id, const char *name, size_t size, void *value);
121
static herr_t H5P__lacc_elink_fapl_enc(const void *value, void **_pp, size_t *size);
122
static herr_t H5P__lacc_elink_fapl_dec(const void **_pp, void *value);
123
static herr_t H5P__lacc_elink_fapl_del(hid_t prop_id, const char *name, size_t size, void *value);
124
static herr_t H5P__lacc_elink_fapl_copy(const char *name, size_t size, void *value);
125
static int    H5P__lacc_elink_fapl_cmp(const void *value1, const void *value2, size_t size);
126
static herr_t H5P__lacc_elink_fapl_close(const char *name, size_t size, void *value);
127
128
/*********************/
129
/* Package Variables */
130
/*********************/
131
132
/* Dataset creation property list class library initialization object */
133
const H5P_libclass_t H5P_CLS_LACC[1] = {{
134
    "link access",        /* Class name for debugging     */
135
    H5P_TYPE_LINK_ACCESS, /* Class type                   */
136
137
    &H5P_CLS_ROOT_g,           /* Parent class                 */
138
    &H5P_CLS_LINK_ACCESS_g,    /* Pointer to class             */
139
    &H5P_CLS_LINK_ACCESS_ID_g, /* Pointer to class ID          */
140
    &H5P_LST_LINK_ACCESS_ID_g, /* Pointer to default property list ID */
141
    H5P__lacc_reg_prop,        /* Default property registration routine */
142
143
    NULL, /* Class creation callback      */
144
    NULL, /* Class creation callback info */
145
    NULL, /* Class copy callback          */
146
    NULL, /* Class copy callback info     */
147
    NULL, /* Class close callback         */
148
    NULL  /* Class close callback info    */
149
}};
150
151
/*****************************/
152
/* Library Private Variables */
153
/*****************************/
154
155
/*******************/
156
/* Local Variables */
157
/*******************/
158
159
/* Property value defaults */
160
static const size_t H5L_def_nlinks_g = H5L_ACS_NLINKS_DEF; /* Default number of soft links to traverse */
161
static const char  *H5L_def_elink_prefix_g =
162
    H5L_ACS_ELINK_PREFIX_DEF;                                     /* Default external link prefix string */
163
static const hid_t    H5L_def_fapl_id_g = H5L_ACS_ELINK_FAPL_DEF; /* Default fapl for external link access */
164
static const unsigned H5L_def_elink_flags_g =
165
    H5L_ACS_ELINK_FLAGS_DEF; /* Default file access flags for external link traversal */
166
static const H5L_elink_cb_t H5L_def_elink_cb_g =
167
    H5L_ACS_ELINK_CB_DEF; /* Default external link traversal callback */
168
#ifdef H5_HAVE_PARALLEL
169
static const H5P_coll_md_read_flag_t H5L_def_coll_md_read_g =
170
    H5L_ACS_COLL_MD_READ_DEF; /* Default setting for the collective metedata read flag */
171
#endif                        /* H5_HAVE_PARALLEL */
172
173
/*-------------------------------------------------------------------------
174
 * Function:    H5P__lacc_reg_prop
175
 *
176
 * Purpose:     Register the dataset creation property list class's properties
177
 *
178
 * Return:      Non-negative on success/Negative on failure
179
 *
180
 *-------------------------------------------------------------------------
181
 */
182
static herr_t
183
H5P__lacc_reg_prop(H5P_genclass_t *pclass)
184
2
{
185
2
    herr_t ret_value = SUCCEED; /* Return value */
186
187
2
    FUNC_ENTER_PACKAGE
188
189
    /* Register property for number of links traversed */
190
2
    if (H5P__register_real(pclass, H5L_ACS_NLINKS_NAME, H5L_ACS_NLINKS_SIZE, &H5L_def_nlinks_g, NULL, NULL,
191
2
                           NULL, H5L_ACS_NLINKS_ENC, H5L_ACS_NLINKS_DEC, NULL, NULL, NULL, NULL) < 0)
192
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
193
194
    /* Register property for external link prefix */
195
2
    if (H5P__register_real(pclass, H5L_ACS_ELINK_PREFIX_NAME, H5L_ACS_ELINK_PREFIX_SIZE,
196
2
                           &H5L_def_elink_prefix_g, NULL, H5L_ACS_ELINK_PREFIX_SET, H5L_ACS_ELINK_PREFIX_GET,
197
2
                           H5L_ACS_ELINK_PREFIX_ENC, H5L_ACS_ELINK_PREFIX_DEC, H5L_ACS_ELINK_PREFIX_DEL,
198
2
                           H5L_ACS_ELINK_PREFIX_COPY, H5L_ACS_ELINK_PREFIX_CMP,
199
2
                           H5L_ACS_ELINK_PREFIX_CLOSE) < 0)
200
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
201
202
    /* Register fapl for link access */
203
2
    if (H5P__register_real(pclass, H5L_ACS_ELINK_FAPL_NAME, H5L_ACS_ELINK_FAPL_SIZE, &H5L_def_fapl_id_g, NULL,
204
2
                           H5L_ACS_ELINK_FAPL_SET, H5L_ACS_ELINK_FAPL_GET, H5L_ACS_ELINK_FAPL_ENC,
205
2
                           H5L_ACS_ELINK_FAPL_DEC, H5L_ACS_ELINK_FAPL_DEL, H5L_ACS_ELINK_FAPL_COPY,
206
2
                           H5L_ACS_ELINK_FAPL_CMP, H5L_ACS_ELINK_FAPL_CLOSE) < 0)
207
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
208
209
    /* Register property for external link file access flags */
210
2
    if (H5P__register_real(pclass, H5L_ACS_ELINK_FLAGS_NAME, H5L_ACS_ELINK_FLAGS_SIZE, &H5L_def_elink_flags_g,
211
2
                           NULL, NULL, NULL, H5L_ACS_ELINK_FLAGS_ENC, H5L_ACS_ELINK_FLAGS_DEC, NULL, NULL,
212
2
                           NULL, NULL) < 0)
213
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
214
215
    /* Register property for external link file traversal callback */
216
    /* (Note: this property should not have an encode/decode callback -QAK) */
217
2
    if (H5P__register_real(pclass, H5L_ACS_ELINK_CB_NAME, H5L_ACS_ELINK_CB_SIZE, &H5L_def_elink_cb_g, NULL,
218
2
                           NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
219
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
220
221
#ifdef H5_HAVE_PARALLEL
222
    /* Register the metadata collective read flag */
223
    if (H5P__register_real(pclass, H5_COLL_MD_READ_FLAG_NAME, H5L_ACS_COLL_MD_READ_SIZE,
224
                           &H5L_def_coll_md_read_g, NULL, NULL, NULL, H5L_ACS_COLL_MD_READ_ENC,
225
                           H5L_ACS_COLL_MD_READ_DEC, NULL, NULL, NULL, NULL) < 0)
226
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
227
#endif /* H5_HAVE_PARALLEL */
228
229
2
done:
230
2
    FUNC_LEAVE_NOAPI(ret_value)
231
2
} /* end H5P__lacc_reg_prop() */
232
233
/*-------------------------------------------------------------------------
234
 * Function:    H5P__lacc_elink_fapl_set
235
 *
236
 * Purpose:     Copies an external link FAPL property when it's set for a property list
237
 *
238
 * Return:      Success:        Non-negative
239
 *              Failure:        Negative
240
 *
241
 *-------------------------------------------------------------------------
242
 */
243
static herr_t
244
H5P__lacc_elink_fapl_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
245
                         size_t H5_ATTR_UNUSED size, void *value)
246
0
{
247
0
    hid_t  l_fapl_id;
248
0
    herr_t ret_value = SUCCEED;
249
250
0
    FUNC_ENTER_PACKAGE
251
252
    /* Sanity check */
253
0
    assert(value);
254
255
    /* Get the FAPL ID */
256
0
    l_fapl_id = *(const hid_t *)value;
257
258
    /* Duplicate the FAPL, if it's non-default */
259
0
    if (l_fapl_id != H5P_DEFAULT) {
260
0
        H5P_genplist_t *l_fapl_plist;
261
262
0
        if (NULL == (l_fapl_plist = (H5P_genplist_t *)H5P_object_verify(l_fapl_id, H5P_FILE_ACCESS, true)))
263
0
            HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list");
264
0
        if (((*(hid_t *)value) = H5P_copy_plist(l_fapl_plist, false)) < 0)
265
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy file access property list");
266
0
    } /* end if */
267
268
0
done:
269
0
    FUNC_LEAVE_NOAPI(ret_value)
270
0
} /* end H5P__lacc_elink_fapl_set() */
271
272
/*-------------------------------------------------------------------------
273
 * Function:    H5P__lacc_elink_fapl_get
274
 *
275
 * Purpose:     Copies an external link FAPL property when it's retrieved from a property list
276
 *
277
 * Return:      Success:        Non-negative
278
 *              Failure:        Negative
279
 *
280
 *-------------------------------------------------------------------------
281
 */
282
static herr_t
283
H5P__lacc_elink_fapl_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
284
                         size_t H5_ATTR_UNUSED size, void *value)
285
0
{
286
0
    hid_t  l_fapl_id;
287
0
    herr_t ret_value = SUCCEED;
288
289
0
    FUNC_ENTER_PACKAGE
290
291
    /* Sanity check */
292
0
    assert(value);
293
294
    /* Get the FAPL ID */
295
0
    l_fapl_id = *(const hid_t *)value;
296
297
    /* Duplicate the FAPL, if it's non-default */
298
0
    if (l_fapl_id != H5P_DEFAULT) {
299
0
        H5P_genplist_t *l_fapl_plist;
300
301
0
        if (NULL == (l_fapl_plist = (H5P_genplist_t *)H5P_object_verify(l_fapl_id, H5P_FILE_ACCESS, true)))
302
0
            HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list");
303
0
        if (((*(hid_t *)value) = H5P_copy_plist(l_fapl_plist, false)) < 0)
304
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy file access property list");
305
0
    } /* end if */
306
307
0
done:
308
0
    FUNC_LEAVE_NOAPI(ret_value)
309
0
} /* end H5P__lacc_elink_fapl_get() */
310
311
/*-------------------------------------------------------------------------
312
 * Function:       H5P__lacc_elink_fapl_enc
313
 *
314
 * Purpose:        Callback routine which is called whenever the elink FAPL
315
 *                 property in the dataset access property list is
316
 *                 encoded.
317
 *
318
 * Return:         Success:        Non-negative
319
 *                 Failure:        Negative
320
 *
321
 *-------------------------------------------------------------------------
322
 */
323
static herr_t
324
H5P__lacc_elink_fapl_enc(const void *value, void **_pp, size_t *size)
325
0
{
326
0
    const hid_t    *elink_fapl = (const hid_t *)value; /* Property to encode */
327
0
    uint8_t       **pp         = (uint8_t **)_pp;
328
0
    H5P_genplist_t *fapl_plist;                 /* Pointer to property list */
329
0
    bool            non_default_fapl = false;   /* Whether the FAPL is non-default */
330
0
    size_t          fapl_size        = 0;       /* FAPL's encoded size */
331
0
    herr_t          ret_value        = SUCCEED; /* Return value */
332
333
0
    FUNC_ENTER_PACKAGE
334
335
    /* Check for non-default FAPL */
336
0
    if (*elink_fapl != H5P_DEFAULT) {
337
0
        if (NULL == (fapl_plist = (H5P_genplist_t *)H5P_object_verify(*elink_fapl, H5P_FILE_ACCESS, true)))
338
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property list");
339
0
        non_default_fapl = true;
340
0
    } /* end if */
341
342
0
    if (NULL != *pp) {
343
        /* Store whether the FAPL is non-default */
344
0
        *(*pp)++ = (uint8_t)non_default_fapl;
345
0
    } /* end if */
346
347
    /* Encode the property list, if non-default */
348
    /* (if *pp == NULL, will only compute the size) */
349
0
    if (non_default_fapl) {
350
0
        if (H5P__encode(fapl_plist, true, NULL, &fapl_size) < 0)
351
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "can't encode property list");
352
353
0
        if (*pp) {
354
0
            uint64_t enc_value;
355
0
            unsigned enc_size;
356
357
            /* encode the length of the plist */
358
0
            enc_value = (uint64_t)fapl_size;
359
0
            enc_size  = H5VM_limit_enc_size(enc_value);
360
0
            assert(enc_size < 256);
361
0
            *(*pp)++ = (uint8_t)enc_size;
362
0
            UINT64ENCODE_VAR(*pp, enc_value, enc_size);
363
364
            /* encode the plist */
365
0
            if (H5P__encode(fapl_plist, true, *pp, &fapl_size) < 0)
366
0
                HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "can't encode property list");
367
368
0
            *pp += fapl_size;
369
0
        }
370
0
        fapl_size += (1 + H5VM_limit_enc_size((uint64_t)fapl_size));
371
0
    } /* end if */
372
373
0
    *size += (1 + fapl_size); /* Non-default flag, plus encoded property list size */
374
375
0
done:
376
0
    FUNC_LEAVE_NOAPI(ret_value)
377
0
} /* end H5P__lacc_elink_fapl_enc() */
378
379
/*-------------------------------------------------------------------------
380
 * Function:       H5P__lacc_elink_fapl_dec
381
 *
382
 * Purpose:        Callback routine which is called whenever the elink FAPL
383
 *                 property in the dataset access property list is
384
 *                 decoded.
385
 *
386
 * Return:         Success:        Non-negative
387
 *                 Failure:        Negative
388
 *
389
 *-------------------------------------------------------------------------
390
 */
391
static herr_t
392
H5P__lacc_elink_fapl_dec(const void **_pp, void *_value)
393
0
{
394
0
    hid_t          *elink_fapl = (hid_t *)_value; /* The elink FAPL value */
395
0
    const uint8_t **pp         = (const uint8_t **)_pp;
396
0
    bool            non_default_fapl;    /* Whether the FAPL is non-default */
397
0
    herr_t          ret_value = SUCCEED; /* Return value */
398
399
0
    FUNC_ENTER_PACKAGE
400
401
    /* Sanity check */
402
0
    assert(pp);
403
0
    assert(*pp);
404
0
    assert(elink_fapl);
405
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
406
407
    /* Determine if the FAPL is non-default */
408
0
    non_default_fapl = (bool)*(*pp)++;
409
410
0
    if (non_default_fapl) {
411
0
        size_t   fapl_size = 0; /* Encoded size of property list */
412
0
        unsigned enc_size;
413
0
        uint64_t enc_value;
414
415
        /* Decode the plist length */
416
0
        enc_size = *(*pp)++;
417
0
        assert(enc_size < 256);
418
0
        UINT64DECODE_VAR(*pp, enc_value, enc_size);
419
0
        fapl_size = (size_t)enc_value;
420
421
        /* Decode the property list */
422
0
        if ((*elink_fapl = H5P__decode(*pp)) < 0)
423
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "can't decode property");
424
425
0
        *pp += fapl_size;
426
0
    } /* end if */
427
0
    else
428
0
        *elink_fapl = H5P_DEFAULT;
429
430
0
done:
431
0
    FUNC_LEAVE_NOAPI(ret_value)
432
0
} /* end H5P__lacc_elink_fapl_dec() */
433
434
/*--------------------------------------------------------------------------
435
 * Function:    H5P__lacc_elink_fapl_del
436
 *
437
 * Purpose:     Close the FAPL for link access
438
 *
439
 * Return:      Success:        Non-negative
440
 *              Failure:        Negative
441
 *
442
 *--------------------------------------------------------------------------
443
 */
444
static herr_t
445
H5P__lacc_elink_fapl_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
446
                         size_t H5_ATTR_UNUSED size, void *value)
447
0
{
448
0
    hid_t  l_fapl_id;
449
0
    herr_t ret_value = SUCCEED;
450
451
0
    FUNC_ENTER_PACKAGE
452
453
    /* Sanity check */
454
0
    assert(value);
455
456
    /* Get the FAPL ID */
457
0
    l_fapl_id = (*(const hid_t *)value);
458
459
    /* Close the FAPL */
460
0
    if (l_fapl_id != H5P_DEFAULT && H5I_dec_ref(l_fapl_id) < 0)
461
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close ID for file access property list");
462
463
0
done:
464
0
    FUNC_LEAVE_NOAPI(ret_value)
465
0
} /* end H5P__lacc_elink_fapl_del() */
466
467
/*--------------------------------------------------------------------------
468
 * Function:    H5P__lacc_elink_fapl_copy
469
 *
470
 * Purpose:     Copy the FAPL for link access
471
 *
472
 * Return:      Success:        Non-negative
473
 *              Failure:        Negative
474
 *
475
 *--------------------------------------------------------------------------
476
 */
477
static herr_t
478
H5P__lacc_elink_fapl_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
479
0
{
480
0
    hid_t  l_fapl_id;
481
0
    herr_t ret_value = SUCCEED;
482
483
0
    FUNC_ENTER_PACKAGE
484
485
    /* Sanity check */
486
0
    assert(value);
487
488
    /* Get the FAPL ID */
489
0
    l_fapl_id = (*(const hid_t *)value);
490
491
    /* Duplicate the FAPL, if it's non-default */
492
0
    if (l_fapl_id != H5P_DEFAULT) {
493
0
        H5P_genplist_t *l_fapl_plist;
494
495
0
        if (NULL == (l_fapl_plist = (H5P_genplist_t *)H5P_object_verify(l_fapl_id, H5P_FILE_ACCESS, true)))
496
0
            HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list");
497
0
        if (((*(hid_t *)value) = H5P_copy_plist(l_fapl_plist, false)) < 0)
498
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy file access property list");
499
0
    } /* end if */
500
501
0
done:
502
0
    FUNC_LEAVE_NOAPI(ret_value)
503
0
} /* end H5P__lacc_elink_fapl_copy() */
504
505
/*-------------------------------------------------------------------------
506
 * Function:       H5P__lacc_elink_fapl_cmp
507
 *
508
 * Purpose:        Callback routine which is called whenever the elink FAPL
509
 *                 property in the link access property list is
510
 *                 compared.
511
 *
512
 * Return:         zero if VALUE1 and VALUE2 are equal, non zero otherwise.
513
 *
514
 *-------------------------------------------------------------------------
515
 */
516
static int
517
H5P__lacc_elink_fapl_cmp(const void *value1, const void *value2, size_t H5_ATTR_UNUSED size)
518
0
{
519
0
    const hid_t    *fapl1 = (const hid_t *)value1;
520
0
    const hid_t    *fapl2 = (const hid_t *)value2;
521
0
    H5P_genplist_t *obj1, *obj2; /* Property lists to compare */
522
0
    int             ret_value = 0;
523
524
0
    FUNC_ENTER_PACKAGE_NOERR
525
526
    /* Check for comparison with default value */
527
0
    if (*fapl1 == 0 && *fapl2 > 0)
528
0
        HGOTO_DONE(1);
529
0
    if (*fapl1 > 0 && *fapl2 == 0)
530
0
        HGOTO_DONE(-1);
531
532
    /* Get the property list objects */
533
0
    obj1 = (H5P_genplist_t *)H5I_object(*fapl1);
534
0
    obj2 = (H5P_genplist_t *)H5I_object(*fapl2);
535
536
    /* Check for NULL property lists */
537
0
    if (obj1 == NULL && obj2 != NULL)
538
0
        HGOTO_DONE(1);
539
0
    if (obj1 != NULL && obj2 == NULL)
540
0
        HGOTO_DONE(-1);
541
0
    if (obj1 && obj2) {
542
0
        herr_t H5_ATTR_NDEBUG_UNUSED status;
543
544
0
        status = H5P__cmp_plist(obj1, obj2, &ret_value);
545
0
        assert(status >= 0);
546
0
    } /* end if */
547
548
0
done:
549
0
    FUNC_LEAVE_NOAPI(ret_value)
550
0
} /* end H5P__lacc_elink_fapl_cmp() */
551
552
/*--------------------------------------------------------------------------
553
 * Function:    H5P__lacc_elink_fapl_close
554
 *
555
 * Purpose:     Close the FAPL for link access
556
 *
557
 * Return:      Success:        Non-negative
558
 *              Failure:        Negative
559
 *
560
 *---------------------------------------------------------------------------
561
 */
562
static herr_t
563
H5P__lacc_elink_fapl_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
564
12
{
565
12
    hid_t  l_fapl_id;
566
12
    herr_t ret_value = SUCCEED;
567
568
12
    FUNC_ENTER_PACKAGE
569
570
    /* Sanity check */
571
12
    assert(value);
572
573
    /* Get the FAPL ID */
574
12
    l_fapl_id = (*(const hid_t *)value);
575
576
    /* Close the FAPL */
577
12
    if ((l_fapl_id > H5P_DEFAULT) && (H5I_dec_ref(l_fapl_id) < 0))
578
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close ID for file access property list");
579
580
12
done:
581
12
    FUNC_LEAVE_NOAPI(ret_value)
582
12
} /* end H5P__lacc_elink_fapl_close() */
583
584
/*-------------------------------------------------------------------------
585
 * Function:    H5P__lacc_elink_pref_set
586
 *
587
 * Purpose:     Copies an external link prefix property when it's set for a property list
588
 *
589
 * Return:      Success:        Non-negative
590
 *              Failure:        Negative
591
 *
592
 *-------------------------------------------------------------------------
593
 */
594
static herr_t
595
H5P__lacc_elink_pref_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
596
                         size_t H5_ATTR_UNUSED size, void *value)
597
0
{
598
0
    FUNC_ENTER_PACKAGE_NOERR
599
600
    /* Sanity check */
601
0
    assert(value);
602
603
    /* Copy the prefix */
604
0
    *(char **)value = H5MM_xstrdup(*(const char **)value);
605
606
0
    FUNC_LEAVE_NOAPI(SUCCEED)
607
0
} /* end H5P__lacc_elink_pref_set() */
608
609
/*-------------------------------------------------------------------------
610
 * Function:    H5P__lacc_elink_pref_get
611
 *
612
 * Purpose:     Copies an external link prefix property when it's retrieved from a property list
613
 *
614
 * Return:      Success:        Non-negative
615
 *              Failure:        Negative
616
 *
617
 *-------------------------------------------------------------------------
618
 */
619
static herr_t
620
H5P__lacc_elink_pref_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
621
                         size_t H5_ATTR_UNUSED size, void *value)
622
0
{
623
0
    FUNC_ENTER_PACKAGE_NOERR
624
625
    /* Sanity check */
626
0
    assert(value);
627
628
    /* Copy the prefix */
629
0
    *(char **)value = H5MM_xstrdup(*(const char **)value);
630
631
0
    FUNC_LEAVE_NOAPI(SUCCEED)
632
0
} /* end H5P__lacc_elink_pref_get() */
633
634
/*-------------------------------------------------------------------------
635
 * Function:       H5P__lacc_elink_pref_enc
636
 *
637
 * Purpose:        Callback routine which is called whenever the elink prefix
638
 *                 property in the dataset access property list is
639
 *                 encoded.
640
 *
641
 * Return:     Success: Non-negative
642
 *       Failure: Negative
643
 *
644
 *-------------------------------------------------------------------------
645
 */
646
static herr_t
647
H5P__lacc_elink_pref_enc(const void *value, void **_pp, size_t *size)
648
0
{
649
0
    const char *elink_pref = *(const char *const *)value;
650
0
    uint8_t   **pp         = (uint8_t **)_pp;
651
0
    size_t      len        = 0;
652
0
    uint64_t    enc_value;
653
0
    unsigned    enc_size;
654
655
0
    FUNC_ENTER_PACKAGE_NOERR
656
657
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
658
659
    /* calculate prefix length */
660
0
    if (NULL != elink_pref)
661
0
        len = strlen(elink_pref);
662
663
0
    enc_value = (uint64_t)len;
664
0
    enc_size  = H5VM_limit_enc_size(enc_value);
665
0
    assert(enc_size < 256);
666
667
0
    if (NULL != *pp) {
668
        /* encode the length of the prefix */
669
0
        *(*pp)++ = (uint8_t)enc_size;
670
0
        UINT64ENCODE_VAR(*pp, enc_value, enc_size);
671
672
        /* encode the prefix */
673
0
        if (NULL != elink_pref) {
674
0
            H5MM_memcpy(*(char **)pp, elink_pref, len);
675
0
            *pp += len;
676
0
        } /* end if */
677
0
    }     /* end if */
678
679
0
    *size += (1 + enc_size);
680
0
    if (NULL != elink_pref)
681
0
        *size += len;
682
683
0
    FUNC_LEAVE_NOAPI(SUCCEED)
684
0
} /* end H5P__lacc_elink_pref_enc() */
685
686
/*-------------------------------------------------------------------------
687
 * Function:       H5P__lacc_elink_pref_dec
688
 *
689
 * Purpose:        Callback routine which is called whenever the elink prefix
690
 *                 property in the dataset access property list is
691
 *                 decoded.
692
 *
693
 * Return:     Success: Non-negative
694
 *       Failure: Negative
695
 *
696
 *-------------------------------------------------------------------------
697
 */
698
static herr_t
699
H5P__lacc_elink_pref_dec(const void **_pp, void *_value)
700
0
{
701
0
    char          **elink_pref = (char **)_value;
702
0
    const uint8_t **pp         = (const uint8_t **)_pp;
703
0
    size_t          len;
704
0
    uint64_t        enc_value; /* Decoded property value */
705
0
    unsigned        enc_size;  /* Size of encoded property */
706
0
    herr_t          ret_value = SUCCEED;
707
708
0
    FUNC_ENTER_PACKAGE
709
710
0
    assert(pp);
711
0
    assert(*pp);
712
0
    assert(elink_pref);
713
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
714
715
    /* Decode the size */
716
0
    enc_size = *(*pp)++;
717
0
    assert(enc_size < 256);
718
719
    /* Decode the value */
720
0
    UINT64DECODE_VAR(*pp, enc_value, enc_size);
721
0
    len = (size_t)enc_value;
722
723
0
    if (0 != len) {
724
        /* Make a copy of the user's prefix string */
725
0
        if (NULL == (*elink_pref = (char *)H5MM_malloc(len + 1)))
726
0
            HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for prefix");
727
0
        strncpy(*elink_pref, *(const char **)pp, len);
728
0
        (*elink_pref)[len] = '\0';
729
730
0
        *pp += len;
731
0
    } /* end if */
732
0
    else
733
0
        *elink_pref = NULL;
734
735
0
done:
736
0
    FUNC_LEAVE_NOAPI(ret_value)
737
0
} /* end H5P__lacc_elink_pref_dec() */
738
739
/*-------------------------------------------------------------------------
740
 * Function:    H5P__lacc_elink_pref_del
741
 *
742
 * Purpose:     Frees memory used to store the external link prefix string
743
 *
744
 * Return:      Non-negative on success/Negative on failure
745
 *
746
 *-------------------------------------------------------------------------
747
 */
748
static herr_t
749
H5P__lacc_elink_pref_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
750
                         size_t H5_ATTR_UNUSED size, void *value)
751
0
{
752
0
    FUNC_ENTER_PACKAGE_NOERR
753
754
0
    assert(value);
755
756
0
    H5MM_xfree(*(void **)value);
757
758
0
    FUNC_LEAVE_NOAPI(SUCCEED)
759
0
} /* end H5P__lacc_elink_pref_del() */
760
761
/*-------------------------------------------------------------------------
762
 * Function:    H5P__lacc_elink_pref_copy
763
 *
764
 * Purpose:     Creates a copy of the external link prefix string
765
 *
766
 * Return:      Non-negative on success/Negative on failure
767
 *
768
 *-------------------------------------------------------------------------
769
 */
770
static herr_t
771
H5P__lacc_elink_pref_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
772
0
{
773
0
    FUNC_ENTER_PACKAGE_NOERR
774
775
0
    assert(value);
776
777
0
    *(char **)value = H5MM_xstrdup(*(const char **)value);
778
779
0
    FUNC_LEAVE_NOAPI(SUCCEED)
780
0
} /* end H5P__lacc_elink_pref_copy() */
781
782
/*-------------------------------------------------------------------------
783
 * Function:       H5P__lacc_elink_pref_cmp
784
 *
785
 * Purpose:        Callback routine which is called whenever the elink prefix
786
 *                 property in the dataset creation property list is
787
 *                 compared.
788
 *
789
 * Return:         zero if VALUE1 and VALUE2 are equal, non zero otherwise.
790
 *
791
 *-------------------------------------------------------------------------
792
 */
793
static int
794
H5P__lacc_elink_pref_cmp(const void *value1, const void *value2, size_t H5_ATTR_UNUSED size)
795
0
{
796
0
    const char *pref1     = *(const char *const *)value1;
797
0
    const char *pref2     = *(const char *const *)value2;
798
0
    int         ret_value = 0;
799
800
0
    FUNC_ENTER_PACKAGE_NOERR
801
802
0
    if (NULL == pref1 && NULL != pref2)
803
0
        HGOTO_DONE(1);
804
0
    if (NULL != pref1 && NULL == pref2)
805
0
        HGOTO_DONE(-1);
806
0
    if (NULL != pref1 && NULL != pref2)
807
0
        ret_value = strcmp(pref1, pref2);
808
809
0
done:
810
0
    FUNC_LEAVE_NOAPI(ret_value)
811
0
} /* end H5P__lacc_elink_pref_cmp() */
812
813
/*-------------------------------------------------------------------------
814
 * Function:    H5P__lacc_elink_pref_close
815
 *
816
 * Purpose:     Frees memory used to store the external link prefix string
817
 *
818
 * Return:      Non-negative on success/Negative on failure
819
 *
820
 *-------------------------------------------------------------------------
821
 */
822
static herr_t
823
H5P__lacc_elink_pref_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
824
12
{
825
12
    FUNC_ENTER_PACKAGE_NOERR
826
827
12
    assert(value);
828
829
12
    H5MM_xfree(*(void **)value);
830
831
12
    FUNC_LEAVE_NOAPI(SUCCEED)
832
12
} /* end H5P__lacc_elink_pref_close() */
833
834
/*-------------------------------------------------------------------------
835
 * Function:    H5Pset_nlinks
836
 *
837
 * Purpose:     Set the number of soft or UD link traversals allowed before
838
 *              the library assumes it has found a cycle and aborts the
839
 *              traversal.
840
 *
841
 *              The limit on soft or UD link traversals is designed to
842
 *              terminate link traversal if one or more links form a cycle.
843
 *              However, users may have a file with a legitimate path
844
 *              formed of a large number of soft or user-defined links.
845
 *              This property can be used to allow traversal of as many
846
 *              links as desired.
847
 *
848
 * Return:  Non-negative on success/Negative on failure
849
 *
850
 *-------------------------------------------------------------------------
851
 */
852
herr_t
853
H5Pset_nlinks(hid_t plist_id, size_t nlinks)
854
0
{
855
0
    H5P_genplist_t *plist;               /* Property list pointer */
856
0
    herr_t          ret_value = SUCCEED; /* Return value */
857
858
0
    FUNC_ENTER_API(FAIL)
859
860
0
    if (nlinks <= 0)
861
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of links must be positive");
862
863
    /* Get the plist structure */
864
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS, false)))
865
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
866
867
    /* Set number of links */
868
0
    if (H5P_set(plist, H5L_ACS_NLINKS_NAME, &nlinks) < 0)
869
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info");
870
871
0
done:
872
0
    FUNC_LEAVE_API(ret_value)
873
0
} /* end H5Pset_nlinks() */
874
875
/*-------------------------------------------------------------------------
876
 * Function:    H5Pget_nlinks
877
 *
878
 * Purpose: Gets the number of soft or user-defined links that can be
879
 *              traversed before a failure occurs.
880
 *
881
 *              Retrieves the current setting for the nlinks property on
882
 *              the given property list.
883
 *
884
 * Return:  Non-negative on success/Negative on failure
885
 *
886
 *-------------------------------------------------------------------------
887
 */
888
herr_t
889
H5Pget_nlinks(hid_t plist_id, size_t *nlinks /*out*/)
890
0
{
891
0
    H5P_genplist_t *plist;               /* Property list pointer */
892
0
    herr_t          ret_value = SUCCEED; /* Return value */
893
894
0
    FUNC_ENTER_API(FAIL)
895
896
0
    if (!nlinks)
897
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer passed in");
898
899
    /* Get the plist structure */
900
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS, true)))
901
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
902
903
    /* Get the current number of links */
904
0
    if (H5P_get(plist, H5L_ACS_NLINKS_NAME, nlinks) < 0)
905
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of links");
906
907
0
done:
908
0
    FUNC_LEAVE_API(ret_value)
909
0
}
910
911
/*-------------------------------------------------------------------------
912
 * Function:    H5Pset_elink_prefix
913
 *
914
 * Purpose:     Set a prefix to be applied to the path of any external links
915
 *              traversed.  The prefix is appended to the filename stored
916
 *              in the external link.
917
 *
918
 * Return:  Non-negative on success/Negative on failure
919
 *
920
 *-------------------------------------------------------------------------
921
 */
922
herr_t
923
H5Pset_elink_prefix(hid_t plist_id, const char *prefix)
924
0
{
925
0
    H5P_genplist_t *plist;               /* Property list pointer */
926
0
    herr_t          ret_value = SUCCEED; /* Return value */
927
928
0
    FUNC_ENTER_API(FAIL)
929
930
    /* Get the plist structure */
931
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS, false)))
932
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
933
934
    /* Set prefix */
935
0
    if (H5P_set(plist, H5L_ACS_ELINK_PREFIX_NAME, &prefix) < 0)
936
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set prefix info");
937
938
0
done:
939
0
    FUNC_LEAVE_API(ret_value)
940
0
} /* end H5Pset_elink_prefix() */
941
942
/*-------------------------------------------------------------------------
943
 * Function:    H5Pget_elink_prefix
944
 *
945
 * Purpose: Gets the prefix to be applied to any external link
946
 *              traversals made using this property list.
947
 *
948
 *              If the pointer is not NULL, it points to a user-allocated
949
 *              buffer.
950
 *
951
 * Return:  Non-negative on success/Negative on failure
952
 *
953
 *-------------------------------------------------------------------------
954
 */
955
ssize_t
956
H5Pget_elink_prefix(hid_t plist_id, char *prefix /*out*/, size_t size)
957
0
{
958
0
    H5P_genplist_t *plist;     /* Property list pointer */
959
0
    char           *my_prefix; /* Library's copy of the prefix */
960
0
    size_t          len;       /* Length of prefix string */
961
0
    ssize_t         ret_value; /* Return value */
962
963
0
    FUNC_ENTER_API(FAIL)
964
965
    /* Get the plist structure */
966
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS, true)))
967
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
968
969
    /* Get the current prefix */
970
0
    if (H5P_peek(plist, H5L_ACS_ELINK_PREFIX_NAME, &my_prefix) < 0)
971
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external link prefix");
972
973
    /* Check for prefix being set */
974
0
    if (my_prefix) {
975
        /* Copy to user's buffer, if given */
976
0
        len = strlen(my_prefix);
977
0
        if (prefix) {
978
0
            strncpy(prefix, my_prefix, size);
979
0
            if (len >= size)
980
0
                prefix[size - 1] = '\0';
981
0
        } /* end if */
982
0
    }     /* end if */
983
0
    else
984
0
        len = 0;
985
986
    /* Set return value */
987
0
    ret_value = (ssize_t)len;
988
989
0
done:
990
0
    FUNC_LEAVE_API(ret_value)
991
0
} /* end H5Pget_elink_prefix() */
992
993
/*-------------------------------------------------------------------------
994
 * Function:    H5Pset_elink_fapl
995
 *
996
 * Purpose:     Sets the file access property list for link access
997
 *
998
 * Return:  Non-negative on success/Negative on failure
999
 *
1000
 *-------------------------------------------------------------------------
1001
 */
1002
herr_t
1003
H5Pset_elink_fapl(hid_t lapl_id, hid_t fapl_id)
1004
0
{
1005
0
    H5P_genplist_t *plist;               /* Property list pointer */
1006
0
    herr_t          ret_value = SUCCEED; /* Return value */
1007
1008
0
    FUNC_ENTER_API(FAIL)
1009
1010
    /* Check arguments */
1011
0
    if (NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS, false)))
1012
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link access property list");
1013
1014
    /* Set the file access property list for the link access */
1015
0
    if (H5P_set(plist, H5L_ACS_ELINK_FAPL_NAME, &fapl_id) < 0)
1016
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fapl for link");
1017
1018
0
done:
1019
0
    FUNC_LEAVE_API(ret_value)
1020
0
} /* end H5Pset_elink_fapl() */
1021
1022
/*-------------------------------------------------------------------------
1023
 * Function:    H5Pget_elink_fapl
1024
 *
1025
 * Purpose: Gets the file access property list identifier that is
1026
 *    set for link access property.
1027
 *
1028
 * Return:  Non-negative on success/Negative on failure
1029
 *
1030
 *-------------------------------------------------------------------------
1031
 */
1032
hid_t
1033
H5Pget_elink_fapl(hid_t lapl_id)
1034
0
{
1035
0
    H5P_genplist_t *plist;     /* Property list pointer */
1036
0
    hid_t           ret_value; /* Return value */
1037
1038
0
    FUNC_ENTER_API(H5I_INVALID_HID)
1039
1040
    /* Get the plist structure */
1041
0
    if (NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS, true)))
1042
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, H5I_INVALID_HID, "can't find object for ID");
1043
1044
0
    if (H5P_get(plist, H5L_ACS_ELINK_FAPL_NAME, &ret_value) < 0)
1045
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't get fapl for links");
1046
1047
0
done:
1048
0
    FUNC_LEAVE_API(ret_value)
1049
0
} /* end H5Pget_elink_fapl() */
1050
1051
/*-------------------------------------------------------------------------
1052
 * Function:    H5Pset_elink_acc_flags
1053
 *
1054
 * Purpose:     Sets the file access flags to be used when traversing an
1055
 *              external link.  This should be either H5F_ACC_RDONLY or
1056
 *              H5F_ACC_RDWR, or H5F_ACC_DEFAULT to unset the value.
1057
 *
1058
 * Return:      Non-negative on success/Negative on failure
1059
 *
1060
 *-------------------------------------------------------------------------
1061
 */
1062
herr_t
1063
H5Pset_elink_acc_flags(hid_t lapl_id, unsigned flags)
1064
0
{
1065
0
    H5P_genplist_t *plist;               /* Property list pointer */
1066
0
    herr_t          ret_value = SUCCEED; /* Return value */
1067
1068
0
    FUNC_ENTER_API(FAIL)
1069
1070
    /* Check that flags are valid */
1071
0
    if ((flags != H5F_ACC_RDWR) && (flags != (H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE)) &&
1072
0
        (flags != H5F_ACC_RDONLY) && (flags != (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ)) &&
1073
0
        (flags != H5F_ACC_DEFAULT))
1074
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags");
1075
1076
    /* Get the plist structure */
1077
0
    if (NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS, false)))
1078
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1079
1080
    /* Set flags */
1081
0
    if (H5P_set(plist, H5L_ACS_ELINK_FLAGS_NAME, &flags) < 0)
1082
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set access flags");
1083
1084
0
done:
1085
0
    FUNC_LEAVE_API(ret_value)
1086
0
} /* end H5Pset_elink_acc_flags() */
1087
1088
/*-------------------------------------------------------------------------
1089
 * Function:    H5Pget_elink_acc_flags
1090
 *
1091
 * Purpose:     Gets the file access flags to be used when traversing an
1092
 *              external link.
1093
 *
1094
 * Return:      Non-negative on success/Negative on failure
1095
 *
1096
 *-------------------------------------------------------------------------
1097
 */
1098
herr_t
1099
H5Pget_elink_acc_flags(hid_t lapl_id, unsigned *flags /*out*/)
1100
0
{
1101
0
    H5P_genplist_t *plist;               /* Property list pointer */
1102
0
    herr_t          ret_value = SUCCEED; /* Return value */
1103
1104
0
    FUNC_ENTER_API(FAIL)
1105
1106
    /* Get the plist structure */
1107
0
    if (NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS, true)))
1108
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1109
1110
    /* Get flags */
1111
0
    if (flags)
1112
0
        if (H5P_get(plist, H5L_ACS_ELINK_FLAGS_NAME, flags) < 0)
1113
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, 0, "can't get access flags");
1114
1115
0
done:
1116
0
    FUNC_LEAVE_API(ret_value)
1117
0
} /* end H5Pget_elink_acc_flags() */
1118
1119
/*-------------------------------------------------------------------------
1120
 * Function:    H5Pset_elink_cb
1121
 *
1122
 * Purpose:     Sets the file access flags to be used when traversing an
1123
 *              external link.  This should be either H5F_ACC_RDONLY or
1124
 *              H5F_ACC_RDWR.
1125
 *
1126
 * Return:      Non-negative on success/Negative on failure
1127
 *
1128
 *-------------------------------------------------------------------------
1129
 */
1130
herr_t
1131
H5Pset_elink_cb(hid_t lapl_id, H5L_elink_traverse_t func, void *op_data)
1132
0
{
1133
0
    H5P_genplist_t *plist;               /* Property list pointer */
1134
0
    H5L_elink_cb_t  cb_info;             /* Callback info struct */
1135
0
    herr_t          ret_value = SUCCEED; /* Return value */
1136
1137
0
    FUNC_ENTER_API(FAIL)
1138
1139
    /* Check if the callback function is NULL and the user data is non-NULL.
1140
     * This is almost certainly an error as the user data will not be used. */
1141
0
    if (!func && op_data)
1142
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback is NULL while user data is not");
1143
1144
    /* Get the plist structure */
1145
0
    if (NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS, false)))
1146
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1147
1148
    /* Populate the callback info struct */
1149
0
    cb_info.func      = func;
1150
0
    cb_info.user_data = op_data;
1151
1152
    /* Set callback info */
1153
0
    if (H5P_set(plist, H5L_ACS_ELINK_CB_NAME, &cb_info) < 0)
1154
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set callback info");
1155
1156
0
done:
1157
0
    FUNC_LEAVE_API(ret_value)
1158
0
} /* end H5Pset_elink_acc_flags() */
1159
1160
/*-------------------------------------------------------------------------
1161
 * Function:    H5Pget_elink_cb
1162
 *
1163
 * Purpose:     Gets the file access flags to be used when traversing an
1164
 *              external link.
1165
 *
1166
 * Return:      Non-negative on success/Negative on failure
1167
 *
1168
 *-------------------------------------------------------------------------
1169
 */
1170
herr_t
1171
H5Pget_elink_cb(hid_t lapl_id, H5L_elink_traverse_t *func /*out*/, void **op_data /*out*/)
1172
0
{
1173
0
    H5P_genplist_t *plist;               /* Property list pointer */
1174
0
    H5L_elink_cb_t  cb_info;             /* Callback info struct */
1175
0
    herr_t          ret_value = SUCCEED; /* Return value */
1176
1177
0
    FUNC_ENTER_API(FAIL)
1178
1179
    /* Get the plist structure */
1180
0
    if (NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS, true)))
1181
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1182
1183
    /* Get callback_info */
1184
0
    if (H5P_get(plist, H5L_ACS_ELINK_CB_NAME, &cb_info) < 0)
1185
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get callback info");
1186
1187
0
    if (func)
1188
0
        *func = cb_info.func;
1189
0
    if (op_data)
1190
0
        *op_data = cb_info.user_data;
1191
1192
0
done:
1193
    FUNC_LEAVE_API(ret_value)
1194
0
} /* end H5Pget_elink_cb() */