X Tutup
Skip to content

Commit ae2a15b

Browse files
committed
macro: introduce TAKE_PTR() macro
This macro will read a pointer of any type, return it, and set the pointer to NULL. This is useful as an explicit concept of passing ownership of a memory area between pointers. This takes inspiration from Rust: https://doc.rust-lang.org/std/option/enum.Option.html#method.take and was suggested by Alan Jenkins (@sourcejedi). It drops ~160 lines of code from our codebase, which makes me like it. Also, I think it clarifies passing of ownership, and thus helps readability a bit (at least for the initiated who know the new macro)
1 parent 1147eef commit ae2a15b

File tree

93 files changed

+215
-379
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+215
-379
lines changed

coccinelle/take-ptr.cocci

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
@@
2+
local idexpression p;
3+
expression q;
4+
@@
5+
- p = q;
6+
- q = NULL;
7+
- return p;
8+
+ return TAKE_PTR(q);
9+
@@
10+
expression p, q;
11+
@@
12+
- p = q;
13+
- q = NULL;
14+
+ p = TAKE_PTR(q);

src/basic/alloc-util.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,12 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
130130
_new_ = alloca_align(_size_, (align)); \
131131
(void*)memset(_new_, 0, _size_); \
132132
})
133+
134+
/* Takes inspiration from Rusts's Option::take() method: reads and returns a pointer, but at the same time resets it to
135+
* NULL. See: https://doc.rust-lang.org/std/option/enum.Option.html#method.take */
136+
#define TAKE_PTR(ptr) \
137+
({ \
138+
typeof(ptr) _ptr_ = (ptr); \
139+
(ptr) = NULL; \
140+
_ptr_; \
141+
})

src/basic/cap-list.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,7 @@ int capability_set_to_string_alloc(uint64_t set, char **s) {
103103

104104
str[n > 0 ? n - 1 : 0] = '\0'; /* truncate the last space, if it's there */
105105

106-
*s = str;
107-
str = NULL;
106+
*s = TAKE_PTR(str);
108107

109108
return 0;
110109
}

src/basic/cgroup-util.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,10 +1424,9 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
14241424
if (r < 0)
14251425
return r;
14261426

1427-
if (c == raw) {
1428-
*cgroup = raw;
1429-
raw = NULL;
1430-
} else {
1427+
if (c == raw)
1428+
*cgroup = TAKE_PTR(raw);
1429+
else {
14311430
char *n;
14321431

14331432
n = strdup(c);
@@ -2010,8 +2009,7 @@ int cg_slice_to_path(const char *unit, char **ret) {
20102009
if (!strextend(&s, e, NULL))
20112010
return -ENOMEM;
20122011

2013-
*ret = s;
2014-
s = NULL;
2012+
*ret = TAKE_PTR(s);
20152013

20162014
return 0;
20172015
}
@@ -2301,8 +2299,7 @@ int cg_mask_to_string(CGroupMask mask, char **ret) {
23012299
assert(s);
23022300

23032301
s[n] = 0;
2304-
*ret = s;
2305-
s = NULL;
2302+
*ret = TAKE_PTR(s);
23062303

23072304
return 0;
23082305
}

src/basic/extract-word.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
194194

195195
finish_force_next:
196196
s[sz] = 0;
197-
*ret = s;
198-
s = NULL;
197+
*ret = TAKE_PTR(s);
199198

200199
return 1;
201200
}

src/basic/fileio.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,7 @@ int read_full_stream(FILE *f, char **contents, size_t *size) {
330330
}
331331

332332
buf[l] = 0;
333-
*contents = buf;
334-
buf = NULL; /* do not free */
333+
*contents = TAKE_PTR(buf);
335334

336335
if (size)
337336
*size = l;
@@ -1432,8 +1431,7 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
14321431
if (fd < 0)
14331432
return -errno;
14341433

1435-
*ret_path = tmp;
1436-
tmp = NULL;
1434+
*ret_path = TAKE_PTR(tmp);
14371435

14381436
return fd;
14391437
}
@@ -1519,8 +1517,7 @@ int read_nul_string(FILE *f, char **ret) {
15191517
return -ENOMEM;
15201518
}
15211519

1522-
*ret = x;
1523-
x = NULL;
1520+
*ret = TAKE_PTR(x);
15241521

15251522
return 0;
15261523
}

src/basic/fs-util.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -458,10 +458,8 @@ int get_files_in_directory(const char *path, char ***list) {
458458
n++;
459459
}
460460

461-
if (list) {
462-
*list = l;
463-
l = NULL; /* avoid freeing */
464-
}
461+
if (list)
462+
*list = TAKE_PTR(l);
465463

466464
return n;
467465
}
@@ -838,10 +836,9 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
838836
}
839837

840838
/* If this is not a symlink, then let's just add the name we read to what we already verified. */
841-
if (!done) {
842-
done = first;
843-
first = NULL;
844-
} else {
839+
if (!done)
840+
done = TAKE_PTR(first);
841+
else {
845842
/* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
846843
if (streq(done, "/"))
847844
*done = '\0';
@@ -863,10 +860,8 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
863860
return -ENOMEM;
864861
}
865862

866-
if (ret) {
867-
*ret = done;
868-
done = NULL;
869-
}
863+
if (ret)
864+
*ret = TAKE_PTR(done);
870865

871866
if (flags & CHASE_OPEN) {
872867
int q;

src/basic/locale-util.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,7 @@ int get_keymaps(char ***ret) {
341341

342342
strv_sort(l);
343343

344-
*ret = l;
345-
l = NULL;
344+
*ret = TAKE_PTR(l);
346345

347346
return 0;
348347
}

src/basic/mount-util.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,8 @@ int name_to_handle_at_loop(
8181

8282
if (name_to_handle_at(fd, path, h, &mnt_id, flags) >= 0) {
8383

84-
if (ret_handle) {
85-
*ret_handle = h;
86-
h = NULL;
87-
}
84+
if (ret_handle)
85+
*ret_handle = TAKE_PTR(h);
8886

8987
if (ret_mnt_id)
9088
*ret_mnt_id = mnt_id;
@@ -951,8 +949,7 @@ int mount_option_mangle(
951949
}
952950

953951
*ret_mount_flags = mount_flags;
954-
*ret_remaining_options = ret;
955-
ret = NULL;
952+
*ret_remaining_options = TAKE_PTR(ret);
956953

957954
return 0;
958955
}

src/basic/parse-util.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,7 @@ int parse_syscall_and_errno(const char *in, char **name, int *error) {
324324
return -EINVAL;
325325

326326
*error = e;
327-
*name = n;
328-
n = NULL;
327+
*name = TAKE_PTR(n);
329328

330329
return 0;
331330
}

0 commit comments

Comments
 (0)
X Tutup