diff --git a/include/strings.h b/include/strings.h index e72fb7776a4..4bb4d27ae9e 100644 --- a/include/strings.h +++ b/include/strings.h @@ -1,4 +1,4 @@ -/* $OpenBSD: strings.h,v 1.6 2017/09/10 21:50:36 schwarze Exp $ */ +/* $OpenBSD: strings.h,v 1.7 2025/10/24 11:30:06 claudio Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -78,6 +78,10 @@ int strncasecmp(const char *, const char *, size_t); int strcasecmp_l(const char *, const char *, locale_t); int strncasecmp_l(const char *, const char *, size_t, locale_t); #endif +#if __POSIX_VISIBLE >= 202405 +int ffsl(long); +int ffsll(long long); +#endif __END_DECLS #endif /* _STRINGS_H_ */ diff --git a/lib/libc/Symbols.list b/lib/libc/Symbols.list index 3ced9a79d2c..d2d1cda3038 100644 --- a/lib/libc/Symbols.list +++ b/lib/libc/Symbols.list @@ -1608,6 +1608,8 @@ bcopy bzero explicit_bzero ffs +ffsl +ffsll index memccpy memchr diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 61ed7d60145..c2d040fcb4b 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -1,4 +1,4 @@ major=102 -minor=0 +minor=1 # note: If changes were made to include/thread_private.h or if system calls # were added/changed then librthread/shlib_version must also be updated. diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc index 204ca1b266f..f8b63304532 100644 --- a/lib/libc/string/Makefile.inc +++ b/lib/libc/string/Makefile.inc @@ -1,13 +1,13 @@ -# $OpenBSD: Makefile.inc,v 1.40 2024/07/14 09:51:18 jca Exp $ +# $OpenBSD: Makefile.inc,v 1.41 2025/10/24 11:30:06 claudio Exp $ # string sources .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/string ${LIBCSRCDIR}/string -SRCS+= explicit_bzero.c memccpy.c memmem.c memrchr.c stpcpy.c stpncpy.c \ - strcasecmp.c strcasecmp_l.c strcasestr.c strcoll.c strcoll_l.c \ - strdup.c strerror.c strerror_l.c strerror_r.c strmode.c \ - strndup.c strnlen.c strsignal.c strtok.c strxfrm.c strxfrm_l.c \ - timingsafe_bcmp.c timingsafe_memcmp.c \ +SRCS+= explicit_bzero.c ffsl.c ffsll.c memccpy.c memmem.c memrchr.c \ + stpcpy.c stpncpy.c strcasecmp.c strcasecmp_l.c strcasestr.c \ + strcoll.c strcoll_l.c strdup.c strerror.c strerror_l.c strerror_r.c \ + strmode.c strndup.c strnlen.c strsignal.c strtok.c strxfrm.c \ + strxfrm_l.c timingsafe_bcmp.c timingsafe_memcmp.c \ wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \ wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcsnlen.c wcspbrk.c wcsrchr.c \ wcsspn.c wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c \ diff --git a/lib/libc/string/ffs.3 b/lib/libc/string/ffs.3 index e78ab99e8f5..630db1c5841 100644 --- a/lib/libc/string/ffs.3 +++ b/lib/libc/string/ffs.3 @@ -27,22 +27,31 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: ffs.3,v 1.11 2019/08/30 18:35:03 deraadt Exp $ +.\" $OpenBSD: ffs.3,v 1.12 2025/10/24 11:30:06 claudio Exp $ .\" -.Dd $Mdocdate: August 30 2019 $ +.Dd $Mdocdate: October 24 2025 $ .Dt FFS 3 .Os .Sh NAME -.Nm ffs +.Nm ffs , +.Nm ffsl , +.Nm ffsll .Nd find first bit set in a bit string .Sh SYNOPSIS .In strings.h .Ft int .Fn ffs "int value" +.Ft int +.Fn ffsl "long value" +.Ft int +.Fn ffsll "long long value" .Sh DESCRIPTION The -.Fn ffs -function finds the first bit set in +.Fn ffs , +.Fn ffsl +and +.Fn ffsll +functions find the first bit set in .Fa value and returns the index of that bit. Bits are numbered starting from 1, starting at the rightmost bit. @@ -54,8 +63,20 @@ The .Fn ffs function conforms to .St -p1003.1-2008 . +The +.Fn ffsl +and +.Fn ffsll +functions conform to +.St -p1003.1-2024 . .Sh HISTORY The .Fn ffs function first appeared in .Bx 4.2 . +The +.Fn ffsl +and +.Fn ffsll +functions first appeared in +.Ox 7.9 . diff --git a/lib/libc/string/ffsl.c b/lib/libc/string/ffsl.c new file mode 100644 index 00000000000..182318c3d65 --- /dev/null +++ b/lib/libc/string/ffsl.c @@ -0,0 +1,17 @@ +/* $OpenBSD: ffsl.c,v 1.1 2025/10/24 11:30:06 claudio Exp $ */ + +/* + * Public domain. + * Written by Claudio Jeker. + */ + +#include + +/* + * ffs -- find the first (least significant) bit set + */ +int +ffsl(long mask) +{ + return (mask ? __builtin_ctzl(mask) + 1 : 0); +} diff --git a/lib/libc/string/ffsll.c b/lib/libc/string/ffsll.c new file mode 100644 index 00000000000..9370c5ae414 --- /dev/null +++ b/lib/libc/string/ffsll.c @@ -0,0 +1,17 @@ +/* $OpenBSD: ffsll.c,v 1.1 2025/10/24 11:30:06 claudio Exp $ */ + +/* + * Public domain. + * Written by Claudio Jeker. + */ + +#include + +/* + * ffs -- find the first (least significant) bit set + */ +int +ffsll(long long mask) +{ + return (mask ? __builtin_ctzll(mask) + 1 : 0); +}