]>
Commit | Line | Data |
---|---|---|
a1eaacb1 | 1 | '\" t |
5b85fb0e | 2 | .\" Copyright 2022 Alejandro Colomar <alx@kernel.org> |
fea681da | 3 | .\" |
5b85fb0e | 4 | .\" SPDX-License-Identifier: Linux-man-pages-copyleft |
fea681da | 5 | .\" |
4c1c5274 | 6 | .TH stpncpy 3 (date) "Linux man-pages (unreleased)" |
fea681da | 7 | .SH NAME |
5b85fb0e AC |
8 | stpncpy, strncpy |
9 | \- zero a fixed-width buffer and | |
10 | copy a string into a character sequence with truncation | |
11 | and zero the rest of it | |
5a517def AC |
12 | .SH LIBRARY |
13 | Standard C library | |
8fc3b2cf | 14 | .RI ( libc ", " \-lc ) |
fea681da MK |
15 | .SH SYNOPSIS |
16 | .nf | |
fea681da | 17 | .B #include <string.h> |
68e4db0a | 18 | .PP |
5b85fb0e AC |
19 | .BI "char *stpncpy(char " dst "[restrict ." sz "], \ |
20 | const char *restrict " src , | |
21 | .BI " size_t " sz ); | |
22 | .BI "char *strncpy(char " dst "[restrict ." sz "], \ | |
23 | const char *restrict " src , | |
24 | .BI " size_t " sz ); | |
fea681da | 25 | .fi |
68e4db0a | 26 | .PP |
d39ad78f | 27 | .RS -4 |
79247bb1 MK |
28 | Feature Test Macro Requirements for glibc (see |
29 | .BR feature_test_macros (7)): | |
d39ad78f | 30 | .RE |
68e4db0a | 31 | .PP |
79247bb1 | 32 | .BR stpncpy (): |
9d2adbae MK |
33 | .nf |
34 | Since glibc 2.10: | |
5c10d2c5 | 35 | _POSIX_C_SOURCE >= 200809L |
9d2adbae MK |
36 | Before glibc 2.10: |
37 | _GNU_SOURCE | |
38 | .fi | |
fea681da | 39 | .SH DESCRIPTION |
5b85fb0e | 40 | These functions copy the string pointed to by |
2d251a70 | 41 | .I src |
5b85fb0e AC |
42 | into a null-padded character sequence at the fixed-width buffer pointed to by |
43 | .IR dst . | |
44 | If the destination buffer, | |
45 | limited by its size, | |
46 | isn't large enough to hold the copy, | |
47 | the resulting character sequence is truncated. | |
48 | For the difference between the two functions, see RETURN VALUE. | |
fea681da | 49 | .PP |
5b85fb0e | 50 | An implementation of these functions might be: |
fea681da | 51 | .PP |
2d251a70 AC |
52 | .in +4n |
53 | .EX | |
54 | char * | |
5b85fb0e | 55 | stpncpy(char *restrict dst, const char *restrict src, size_t sz) |
2d251a70 | 56 | { |
5b85fb0e AC |
57 | bzero(dst, sz); |
58 | return mempcpy(dst, src, strnlen(src, sz)); | |
59 | } | |
2d251a70 | 60 | |
5b85fb0e AC |
61 | char * |
62 | strncpy(char *restrict dst, const char *restrict src, size_t sz) | |
63 | { | |
64 | stpncpy(dst, src, sz); | |
65 | return dst; | |
2d251a70 AC |
66 | } |
67 | .EE | |
68 | .in | |
47297adb | 69 | .SH RETURN VALUE |
5b85fb0e | 70 | .TP |
60a90ecd | 71 | .BR stpncpy () |
5b85fb0e AC |
72 | returns a pointer to |
73 | one after the last character in the destination character sequence. | |
74 | .TP | |
75 | .BR strncpy () | |
76 | returns | |
77 | .IR dst . | |
f27f40b7 | 78 | .SH ATTRIBUTES |
ea1e1b75 PH |
79 | For an explanation of the terms used in this section, see |
80 | .BR attributes (7). | |
c466875e MK |
81 | .ad l |
82 | .nh | |
ea1e1b75 PH |
83 | .TS |
84 | allbox; | |
c466875e | 85 | lbx lb lb |
ea1e1b75 PH |
86 | l l l. |
87 | Interface Attribute Value | |
88 | T{ | |
5b85fb0e AC |
89 | .BR stpncpy (), |
90 | .BR strncpy () | |
ea1e1b75 PH |
91 | T} Thread safety MT-Safe |
92 | .TE | |
c466875e MK |
93 | .hy |
94 | .ad | |
95 | .sp 1 | |
3113c7f3 | 96 | .SH STANDARDS |
5b85fb0e AC |
97 | .TP |
98 | .BR stpncpy () | |
99 | POSIX.1-2008. | |
100 | .\" Before that, it was a GNU extension. | |
101 | .\" It first appeared in glibc 1.07 in 1993. | |
102 | .TP | |
103 | .BR strncpy () | |
104 | POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD. | |
105 | .SH CAVEATS | |
106 | The name of these functions is confusing. | |
107 | These functions produce a null-padded character sequence, | |
108 | not a string (see | |
109 | .BR string_copying (7)). | |
110 | .PP | |
111 | It's impossible to distinguish truncation by the result of the call, | |
112 | from a character sequence that just fits the destination buffer; | |
113 | truncation should be detected by | |
114 | comparing the length of the input string | |
115 | with the size of the destination buffer. | |
116 | .PP | |
117 | If you're going to use this function in chained calls, | |
118 | it would be useful to develop a similar function that accepts | |
119 | a pointer to the end (one after the last element) of the destination buffer | |
120 | instead of its size. | |
121 | .SH EXAMPLES | |
122 | .\" SRC BEGIN (stpncpy.c) | |
123 | .EX | |
124 | #include <err.h> | |
125 | #include <stdio.h> | |
126 | #include <stdlib.h> | |
127 | #include <string.h> | |
128 | ||
129 | int | |
130 | main(void) | |
131 | { | |
132 | char *p; | |
133 | char buf1[20]; | |
134 | char buf2[20]; | |
135 | size_t len; | |
136 | ||
137 | if (sizeof(buf1) < strlen("Hello world!")) | |
138 | warnx("stpncpy: truncating character sequence"); | |
139 | p = stpncpy(buf1, "Hello world!", sizeof(buf1)); | |
140 | len = p \- buf1; | |
141 | ||
142 | printf("[len = %zu]: ", len); | |
143 | printf("%.*s\en", (int) len, buf1); // "Hello world!" | |
144 | ||
145 | if (sizeof(buf2) < strlen("Hello world!")) | |
146 | warnx("strncpy: truncating character sequence"); | |
147 | strncpy(buf2, "Hello world!", sizeof(buf)); | |
148 | len = strnlen(buf2, sizeof(buf2)); | |
149 | ||
150 | printf("[len = %zu]: ", len); | |
151 | printf("%.*s\en", (int) len, buf2); // "Hello world!" | |
152 | ||
153 | exit(EXIT_SUCCESS); | |
154 | } | |
155 | .EE | |
156 | .\" SRC END | |
47297adb | 157 | .SH SEE ALSO |
5b85fb0e AC |
158 | .BR wcpncpy (3), |
159 | .BR string_copying (7) |