Skip to content

Commit 418bffd

Browse files
committed
Add c.s.j.p.bsd.ExtAttr and c.s.j.p.bsd.ExtAttrUtil to wrap BSD <sys/extattr.h> system calls
1 parent 43b5f76 commit 418bffd

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Features
1010
* [#1534](https://github.com/java-native-access/jna/pull/1534): Add `GetMethod`, `Put`, `SpawnInstance` to `c.s.j.p.win32.COM.WbemCli#IWbemClassObject` and `ExecMethod` to `c.s.j.p.win32.COM.WbemCli#IWbemServices` - [@faddom](https://github.com/faddom).
1111
* [#1544](https://github.com/java-native-access/jna/pull/1544): Add `GetPriorityClass`, `SetPriorityClass`, `GetThreadPriority`, `SetThreadPriority` and associated constants to `c.s.j.p.win32.Kernel32` - [@dEajL3kA](https://github.com/dEajL3kA).
1212
* [#1548](https://github.com/java-native-access/jna/pull/1548): Make interface `c.s.j.p.mac.XAttr public` - [@matthiasblaesing](https://github.com/matthiasblaesing).
13+
* [#1551](https://github.com/java-native-access/jna/pull/1549): Add `c.s.j.p.bsd.ExtAttr` and `c.s.j.p.bsd.ExtAttrUtil` to wrap BSD [<sys/extattr.h>](https://man.freebsd.org/cgi/man.cgi?query=extattr&sektion=2) system calls. [@rednoah](https://github.com/rednoah).
1314

1415
Bug Fixes
1516
---------
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* Copyright (c) 2023 Reinhard Pointner, All Rights Reserved
2+
*
3+
* The contents of this file is dual-licensed under 2
4+
* alternative Open Source/Free licenses: LGPL 2.1 or later and
5+
* Apache License 2.0. (starting with JNA version 4.0.0).
6+
*
7+
* You can freely decide which license you want to apply to
8+
* the project.
9+
*
10+
* You may obtain a copy of the LGPL License at:
11+
*
12+
* http://www.gnu.org/licenses/licenses.html
13+
*
14+
* A copy is also included in the downloadable source code package
15+
* containing JNA, in file "LGPL2.1".
16+
*
17+
* You may obtain a copy of the Apache License at:
18+
*
19+
* http://www.apache.org/licenses/
20+
*
21+
* A copy is also included in the downloadable source code package
22+
* containing JNA, in file "AL2.0".
23+
*/
24+
package com.sun.jna.platform.bsd;
25+
26+
import java.nio.ByteBuffer;
27+
28+
import com.sun.jna.Library;
29+
import com.sun.jna.Native;
30+
import com.sun.jna.platform.unix.LibCAPI.size_t;
31+
import com.sun.jna.platform.unix.LibCAPI.ssize_t;
32+
33+
public interface ExtAttr extends Library {
34+
35+
ExtAttr INSTANCE = Native.load(null, ExtAttr.class);
36+
37+
int EXTATTR_NAMESPACE_USER = 0x1;
38+
39+
ssize_t extattr_get_file(String path, int attrnamespace, String attrname, ByteBuffer data, size_t nbytes);
40+
41+
ssize_t extattr_set_file(String path, int attrnamespace, String attrname, ByteBuffer data, size_t nbytes);
42+
43+
int extattr_delete_file(String path, int attrnamespace, String attrname);
44+
45+
ssize_t extattr_list_file(String path, int attrnamespace, ByteBuffer data, size_t nbytes);
46+
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/* Copyright (c) 2023 Reinhard Pointner, All Rights Reserved
2+
*
3+
* The contents of this file is dual-licensed under 2
4+
* alternative Open Source/Free licenses: LGPL 2.1 or later and
5+
* Apache License 2.0. (starting with JNA version 4.0.0).
6+
*
7+
* You can freely decide which license you want to apply to
8+
* the project.
9+
*
10+
* You may obtain a copy of the LGPL License at:
11+
*
12+
* http://www.gnu.org/licenses/licenses.html
13+
*
14+
* A copy is also included in the downloadable source code package
15+
* containing JNA, in file "LGPL2.1".
16+
*
17+
* You may obtain a copy of the Apache License at:
18+
*
19+
* http://www.apache.org/licenses/
20+
*
21+
* A copy is also included in the downloadable source code package
22+
* containing JNA, in file "AL2.0".
23+
*/
24+
package com.sun.jna.platform.bsd;
25+
26+
import static java.util.Collections.*;
27+
28+
import java.io.IOException;
29+
import java.io.UnsupportedEncodingException;
30+
import java.nio.ByteBuffer;
31+
import java.util.ArrayList;
32+
import java.util.List;
33+
34+
import com.sun.jna.Native;
35+
import com.sun.jna.platform.unix.LibCAPI.size_t;
36+
37+
public class ExtAttrUtil {
38+
39+
public static List<String> list(String path) throws IOException {
40+
// get required buffer size
41+
long bufferLength = ExtAttr.INSTANCE.extattr_list_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, null, new size_t(0)).longValue();
42+
43+
if (bufferLength < 0) {
44+
throw new IOException("errno: " + Native.getLastError());
45+
}
46+
47+
if (bufferLength == 0) {
48+
return emptyList();
49+
}
50+
51+
ByteBuffer buffer = ByteBuffer.allocate((int) bufferLength);
52+
long valueLength = ExtAttr.INSTANCE.extattr_list_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, buffer, new size_t(bufferLength)).longValue();
53+
54+
if (valueLength < 0) {
55+
throw new IOException("errno: " + Native.getLastError());
56+
}
57+
58+
return decodeStringList(buffer);
59+
}
60+
61+
public static ByteBuffer get(String path, String name) throws IOException {
62+
// get required buffer size
63+
long bufferLength = ExtAttr.INSTANCE.extattr_get_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, name, null, new size_t(0)).longValue();
64+
65+
if (bufferLength < 0) {
66+
throw new IOException("errno: " + Native.getLastError());
67+
}
68+
69+
if (bufferLength == 0) {
70+
return ByteBuffer.allocate(0);
71+
}
72+
73+
ByteBuffer buffer = ByteBuffer.allocate((int) bufferLength);
74+
long valueLength = ExtAttr.INSTANCE.extattr_get_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, name, buffer, new size_t(bufferLength)).longValue();
75+
76+
if (valueLength < 0) {
77+
throw new IOException("errno: " + Native.getLastError());
78+
}
79+
80+
return buffer;
81+
}
82+
83+
public static void set(String path, String name, ByteBuffer value) throws IOException {
84+
long r = ExtAttr.INSTANCE.extattr_set_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, name, value, new size_t(value.remaining())).longValue();
85+
if (r < 0) {
86+
throw new IOException("errno: " + Native.getLastError());
87+
}
88+
}
89+
90+
public static void delete(String path, String name) throws IOException {
91+
int r = ExtAttr.INSTANCE.extattr_delete_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, name);
92+
if (r < 0) {
93+
throw new IOException("errno: " + Native.getLastError());
94+
}
95+
}
96+
97+
private static List<String> decodeStringList(ByteBuffer buffer) {
98+
List<String> list = new ArrayList<String>();
99+
100+
while (buffer.hasRemaining()) {
101+
int length = buffer.get() & 0xFF;
102+
byte[] value = new byte[length];
103+
buffer.get(value);
104+
105+
try {
106+
list.add(new String(value, "UTF-8"));
107+
} catch (UnsupportedEncodingException e) {
108+
throw new RuntimeException(e);
109+
}
110+
}
111+
112+
return list;
113+
}
114+
115+
}

0 commit comments

Comments
 (0)