---
name: "key"
section: "3elektra"
platform: "linux"
package: "elektra-doc"
version: "0.8.7-4"
release: "Debian 8 (Jessie)"
platforms: ["linux"]
url: "https://new.carta.tech/key/3elektra"
---

# key(3elektra)

A Key is the essential class that encapsulates key name , value and metainfo .

## NAME

Key -

A Key is the essential class that encapsulates key **name** , **value**  and **metainfo** .

### Modules

**Basic Methods**\
 *Key construction and initialization methods.*  **Meta Info Manipulation Methods**\
 *Methods to do various operations on Key metainfo.*  **Methods for Making Tests**\
 *Methods to do various tests on Keys.*  **Name Manipulation Methods**\
 *Methods to do various operations on Key names.*  **Value Manipulation Methods**\
 *Methods to do various operations on Key values.*

### Enumerations

enum **keyswitch\_t** { **KEY\_NAME** =1, **KEY\_VALUE** =1\<\<1, **KEY\_OWNER** =1\<\<2, **KEY\_COMMENT** =1\<\<3, **KEY\_BINARY** =1\<\<4, **KEY\_UID** =1\<\<5, **KEY\_GID** =1\<\<6, **KEY\_MODE** =1\<\<7, **KEY\_ATIME** =1\<\<8, **KEY\_MTIME** =1\<\<9, **KEY\_CTIME** =1\<\<10, **KEY\_SIZE** =1\<\<11, **KEY\_DIR** =1\<\<14, **KEY\_END** =0 }\

### Functions

Key \* **keyNew** (const char \*name,...)\
 Key \* **keyDup** (const Key \*source)\
 int **keyCopy** (Key \*dest, const Key \*source)\
 int **keyDel** (Key \*key)\
 int **keyClear** (Key \*key)\
 ssize\_t **keyIncRef** (Key \*key)\
 ssize\_t **keyDecRef** (Key \*key)\
 ssize\_t **keyGetRef** (const Key \*key)\

## Detailed Description

A Key is the essential class that encapsulates key **name** , **value**  and **metainfo** .

## Enumeration Type Documentation

### enum keyswitch\_t

Switches to denote the various Key attributes in methods throughout this library.

This enum switch provide a flag for every metadata in a key.

In case of **keyNew()** they give Information what Parameter comes next.

**See also:**

**keyNew()**

ksToStream(), keyToStream()

**Enumerator**

- *KEY\_NAME*

  *Flag for the key name*

- *KEY\_VALUE*

  *Flag for the key data*

- *KEY\_OWNER*

  *Flag for the key user domain*

- *KEY\_COMMENT*

  *Flag for the key comment*

- *KEY\_BINARY*

  *Flag if the key is binary*

- *KEY\_UID*

  *Flag for the key UID*

- *KEY\_GID*

  *Flag for the key GID*

- *KEY\_MODE*

  *Flag for the key permissions*

- *KEY\_ATIME*

  *Flag for the key access time*

- *KEY\_MTIME*

  *Flag for the key change time*

- *KEY\_CTIME*

  *Flag for the key status change time*

- *KEY\_SIZE*

  *Flag for maximum size to limit value*

- *KEY\_DIR*

  *Flag for the key directories*

- *KEY\_END*

  *Used as a parameter terminator to* **keyNew()**

## Function Documentation

### int keyClear (Key \*key)

*Key Object Cleaner.*

*Will reset all internal data.*

*After this call you will receive a fresh key.*

*The reference counter will stay unmodified.*

**Note:**

*that you might also clear() all aliases with this operation.*

```
int f (Key *k)
{
        keyClear (k);
        // you have a fresh key k here
        keySetString (k, "value");
        // the caller will get an empty key k with an value
}
```

**Returns:**

*returns 0 on success*

*-1 on null pointer*

**Parameters:**

*key the key object to work with*

### int keyCopy (Key \*dest, const Key \*source)

*Copy or Clear a key.*

*Most often you may prefer* **keyDup()** *which allocates a new key and returns a duplication of another key.*

*But when you need to copy into an existing key, e.g. because it was passed by a pointer in a function you can do so:*

```
void h (Key *k)
{
        // receive key c
        keyCopy (k, c);
        // the caller will see the changed key k
}
```

*The reference counter will not be changed for both keys. Affiliation to keysets are also not affected.*

*When you pass a NULL-pointer as source the data of dest will be cleaned completely (except reference counter, see* **keyClear()***) and you get a fresh dest key.*

```
void g (Key *k)
{
        keyCopy (k, 0);
        // k is now an empty and fresh key
}
```

*The meta data will be duplicated for the destination key. So it will not take much additional space, even with lots of metadata.*

*If you want to copy all metadata, but keep the old value you can use* **keyCopy()** *too.*

```
void j (Key *k)
{
        size_t size = keyGetValueSize (k);
        char *value = malloc (size);
        int bstring = keyIsString (k);
        // receive key c
        memcpy (value, keyValue(k), size);
        keyCopy (k, c);
        if (bstring) keySetString (k, value);
        else keySetBinary (k, value, size);
        free (value);
        // the caller will see the changed key k
        // with the metadata from c
}
```

**Note:**

*Next to the value itself we also need to remember if the value was string or binary. So in fact the meta data of the resulting key k in that example is not a complete duplicate, because the meta data 'binary' may differ. Similar considerations might be necessary for the type of the key and so on, depending on the concrete situation.*

**Parameters:**

*dest the key which will be written to* \
 *source the key which should be copied or NULL to clean the destination key*

**Returns:**

*-1 on failure when a NULL pointer was passed for dest or a dynamic property could not be written. Both name and value are empty then.*

*0 when dest was cleaned*

*1 when source was successfully copied*

**See also:**

**keyDup()** *to get a duplication of a* **Key**

### ssize\_t keyDecRef (Key \*key)

*Decrement the viability of a key object.*

*The references will be decremented for* **ksPop()** *or successful calls of* **ksLookup()** *with the option KDB\_O\_POP. It will also be decremented with an following* **keyDel()** *in the case that an old key is replaced with another key with the same name.*

*The reference counter can't be decremented once it reached 0. In that situation nothing will happen and 0 will be returned.*

**Note:**

**keyDup()** *will reset the references for dupped key.*

**Returns:**

*the value of the new reference counter*

*-1 on null pointer*

*0 when the key is ready to be freed*

**Parameters:**

*key the key object to work with*

**See also:**

**keyGetRef()***,* **keyDel()***,* **keyIncRef()**

### int keyDel (Key \*key)

*A destructor for Key objects.*

*Every key created by* **keyNew()** *must be deleted with* **keyDel()***.*

*It is save to delete keys which are in a keyset, the number of references will be returned then.*

*It is save to delete a nullpointer, -1 will be returned then.*

*It is also save to delete a multiple referenced key, nothing will happen then and the reference counter will be returned.*

**Parameters:**

*key the key object to delete*

**See also:**

**keyNew()***, keyInc(),* **keyGetRef()**

**Returns:**

*the value of the reference counter if the key is within keyset(s)*

*0 when the key was freed*

*-1 on null pointers*

### Key\* keyDup (const Key \*source)

*Return a duplicate of a key.*

*Memory will be allocated as needed for dynamic properties.*

*The new key will not be member of any KeySet and will start with a new reference counter at 0. A subsequent* **keyDel()** *will delete the key.*

```
int f (const Key * source)
{
        Key * dup = keyDup (source);
        // work with duplicate
        keyDel (dup);
        // everything related to dup is freed
        // and source is unchanged
}
```

*Like for a new key after* **keyNew()** *a subsequent* **ksAppend()** *makes a KeySet to take care of the lifecycle of the key.*

```
int g (const Key * source, KeySet * ks)
{
        Key * dup = keyDup (source);
        // work with duplicate
        ksAppendKey (ks, dup);
        // ksDel(ks) will also free the duplicate
        // source remains unchanged.
}
```

*Duplication of keys should be preferred to* **keyNew()***, because data like owner can be filled with a copy of the key instead of asking the environment. It can also be optimized in the checks, because the keyname is known to be valid.*

**Parameters:**

*source has to be an initializised source Key*

**Returns:**

*0 failure or on NULL pointer*

*a fully copy of source on success*

**See also:**

**ksAppend()***,* **keyDel()***,* **keyNew()**

### ssize\_t keyGetRef (const Key \*key)

*Return how many references the key has.*

*The references will be incremented on successful calls to* **ksAppendKey()** *or* **ksAppend()***.*

**Note:**

**keyDup()** *will reset the references for dupped key.*

*For your own applications you can use* **keyIncRef()** *and* **keyDecRef()** *for reference counting. Keys with zero references will be deleted when using* **keyDel()***.*

**Parameters:**

*key the key object to work with*

**Returns:**

*the number of references*

*-1 on null pointer*

**See also:**

**keyIncRef()** *and* **keyDecRef()**

### ssize\_t keyIncRef (Key \*key)

*Increment the viability of a key object.*

*This function is intended for applications using their own reference counter for key objects. With it you can increment the reference and thus avoid destruction of the object in a subsequent* **keyDel()***.*

```
Key *k;
keyInc (k);
function_that_keyDec(k);
// work with k
keyDel (k); // now really free it
```

*The reference counter can't be incremented once it reached SSIZE\_MAX. In that situation nothing will happen and SSIZE\_MAX will be returned.*

**Note:**

**keyDup()** *will reset the references for dupped key.*

**Returns:**

*the value of the new reference counter*

*-1 on null pointer*

*SSIZE\_MAX when maximum exceeded*

**Parameters:**

*key the key object to work with*

**See also:**

**keyGetRef()***,* **keyDecRef()***,* **keyDel()**

### Key\* keyNew (const char \*name, ...)

*A practical way to fully create a Key object in one step.*

*This function tries to mimic the C++ way for constructors.*

*To just get a key object, simple do:*

```
Key *k = keyNew(0);
// work with it
keyDel (k);
```

*If you want the key object to contain a name, value, comment and other meta info read on.*

**Note:**

*When you already have a key with similar properties its easier and cheaper to* **keyDup()** *the key.*

*Due to ABI compatibility, the* `Key` *structure is not defined in kdb.h, only declared. So you can only declare* `pointers` *to* `Keys` *in your program, and allocate and free memory for them with* **keyNew()** *and* **keyDel()** *respectively. See http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html#AEN135*

*You can call it in many different ways depending on the attribute tags you pass as parameters. Tags are represented as the* **keyswitch\_t** *values, and tell* **keyNew()** *which Key attribute comes next.*

*The simplest and minimum way to use it is with no tags, only a key name:*

```
Key *nullKey,*emptyNamedKey;
// Create a key that has no name, is completely empty, but is initialized
nullKey=keyNew(0);
keyDel (nullKey);
// Is the same as above
nullKey=keyNew("", KEY_END);
keyDel (nullKey);
// Create and initialize a key with a name and nothing else
emptyNamedKey=keyNew("user/some/example",KEY_END);
keyDel (emptyNamedKey);
```

**keyNew()** *allocates memory for a key object and cleans everything up. After that, it processes the given argument list.*

*The Key attribute tags are the following:*

- •

  *keyswitch\_t::KEY\_TYPE* \
  \
    *Next parameter is a type of the value. Default assumed is KEY\_TYPE\_UNDEFINED. Set this attribute so that a subsequent KEY\_VALUE can toggle to* **keySetString()** *or* **keySetBinary()** *regarding to* **keyIsString()** *or* **keyIsBinary()***. If you don't use KEY\_TYPE but a KEY\_VALUE follows afterwards, KEY\_TYPE\_STRING will be used.*

- •

  *keyswitch\_t::KEY\_SIZE* \
  \
    *Define a maximum length of the value. This is especially useful for setting a binary key. So make sure you use that before you KEY\_VALUE for binary keys.*

- •

  *keyswitch\_t::KEY\_VALUE* \
  \
    *Next parameter is a pointer to the value that will be set to the key If no keyswitch\_t::KEY\_TYPE was used before, keyswitch\_t::KEY\_TYPE\_STRING is assumed. If KEY\_TYPE was previously passed with a KEY\_TYPE\_BINARY, you should have passed KEY\_SIZE before! Otherwise it will be cut of with first \\0 in string!*

- •

  *keyswitch\_t::KEY\_UID,* `keyswitch_t::KEY_GID` \
  \
    *Next parameter is taken as the UID (uid\_t) or GID (gid\_t) that will be defined on the key. See* **keySetUID()** *and* **keySetGID()***.*

- •

  *keyswitch\_t::KEY\_MODE* \
  \
    *Next parameter is taken as mode permissions (int) to the key. See* **keySetMode()***.*

- •

  *keyswitch\_t::KEY\_DIR* \
  \
    *Define that the key is a directory rather than a ordinary key. This means its executable bits in its mode are set. This option allows the key to have subkeys. See* **keySetDir()***.*

- •

  *keyswitch\_t::KEY\_OWNER* \
  \
    *Next parameter is the owner. See* **keySetOwner()***.*

- •

  *keyswitch\_t::KEY\_COMMENT* \
  \
    *Next parameter is a comment. See* **keySetComment()***.*

- •

  *keyswitch\_t::KEY\_END* \
  \
    *Must be the last parameter passed to* **keyNew()***. It is always required, unless the* `keyName` *is 0.*

**Example:**

```
KeySet *ks=ksNew(0);
ksAppendKey(ks,keyNew(0));       // an empty key
ksAppendKey(ks,keyNew("user/sw",              // the name of the key
        KEY_END));                      // no more args
ksAppendKey(ks,keyNew("user/tmp/ex1",
        KEY_VALUE,"some data",          // set a string value
        KEY_END));                      // end of args
ksAppendKey(ks,keyNew("user/tmp/ex2",
        KEY_VALUE,"some data",          // with a simple value
        KEY_MODE,0777,                  // permissions
        KEY_END));                      // end of args
ksAppendKey(ks,keyNew("user/tmp/ex4",
        KEY_TYPE,KEY_TYPE_BINARY,       // key type
        KEY_SIZE,7,                     // assume binary length 7
        KEY_VALUE,"some data",          // value that will be truncated in 7 bytes
        KEY_COMMENT,"value is truncated",
        KEY_OWNER,"root",               // owner (not uid) is root
        KEY_UID,0,                      // root uid
        KEY_END));                      // end of args
ksAppendKey(ks,keyNew("user/tmp/ex5",
        KEY_TYPE,
                KEY_TYPE_DIR | KEY_TYPE_BINARY,// dir key with a binary value
        KEY_SIZE,7,
        KEY_VALUE,"some data",          // value that will be truncated in 7 bytes
        KEY_COMMENT,"value is truncated",
        KEY_OWNER,"root",               // owner (not uid) is root
        KEY_UID,0,                      // root uid
        KEY_END));                      // end of args
ksDel(ks);
```

*The reference counter (see* **keyGetRef()***) will be initialized with 0, that means a subsequent call of* **keyDel()** *will delete the key. If you append the key to a keyset the reference counter will be incremented by one (see keyInc()) and the key can't be be deleted by a* **keyDel()***.*

```
Key *k = keyNew(0); // ref counter 0
ksAppendKey(ks, k); // ref counter of key 1
ksDel(ks); // key will be deleted with keyset
```

*If you increment only by one with keyInc() the same as said above is valid:*

```
Key *k = keyNew(0); // ref counter 0
keyIncRef(k); // ref counter of key 1
keyDel(k);    // has no effect
keyDecRef(k); // ref counter back to 0
keyDel(k);    // key is now deleted
```

*If you add the key to more keySets:*

```
Key *k = keyNew(0); // ref counter 0
ksAppendKey(ks1, k); // ref counter of key 1
ksAppendKey(ks2, k); // ref counter of key 2
ksDel(ks1); // ref counter of key 1
ksDel(ks2); // k is now deleted
```

*or use keyInc() more than once:*

```
Key *k = keyNew(0); // ref counter 0
keyIncRef(k); // ref counter of key 1
keyDel (k);   // has no effect
keyIncRef(k); // ref counter of key 2
keyDel (k);   // has no effect
keyDecRef(k); // ref counter of key 1
keyDel (k);   // has no effect
keyDecRef(k); // ref counter is now 0
keyDel (k); // k is now deleted
```

*they key won't be deleted by a* **keyDel()** *as long refcounter is not 0.*

*The key's sync bit will always be set for any call, except:*

```
Key *k = keyNew(0);
// keyNeedSync() will be false
```

**Parameters:**

*name a valid name to the key, or NULL to get a simple initialized, but really empty, object*

**See also:**

**keyDel()**

**Returns:**

*a pointer to a new allocated and initialized Key object.*

**Return values:**

*NULL on malloc error or if an invalid* `name` *was passed (see* **keySetName()***).*

## Author

*Generated automatically by Doxygen for Elektra from the source code.*
