hi all,
i am writing a code in which i have a char buffer "cwdir[]"
which hold the current working directory by calling the function
getcwd(). later i change the directory to "/" as i have to make my
code Deamon. and later again i want to run some other executable
available at the path holded by the "cwdir[]" using the system()
system call. presently i concatenate program name (to be executed) to
the "cwdir[]" and use system(chdir)to run the program.
do we have any facility to automate this process as i need to run
many other programs also using the system() system call for ex as we
can use the ## symbol to cancatenate in macro ...
--shri 37 8437 sh*********@yahoo.com (Shri) wrote in
news:8a**************************@posting.google.c om: i am writing a code in which i have a char buffer "cwdir[]" which hold the current working directory by calling the function getcwd(). later i change the directory to "/" as i have to make my code Deamon. and later again i want to run some other executable available at the path holded by the "cwdir[]" using the system() system call. presently i concatenate program name (to be executed) to the "cwdir[]" and use system(chdir)to run the program.
do we have any facility to automate this process as i need to run many other programs also using the system() system call for ex as we can use the ## symbol to cancatenate in macro ...
Does strcat() help? If you need fancier concatenation, sprintf() might be
an option.
--
- Mark ->
--
Shri wrote: i am writing a code in which i have a char buffer "cwdir[]" which hold the current working directory by calling the function getcwd(). later i change the directory to "/" as i have to make my code Deamon. and later again i want to run some other executable available at the path holded by the "cwdir[]" using the system() system call. presently i concatenate program name (to be executed) to the "cwdir[]" and use system(chdir)to run the program. do we have any facility to automate this process as i need to run many other programs also using the system() system call for ex as we can use the ## symbol to cancatenate in macro ...
I *think* that what you are asking for is strcpy(), strcat(), etc.
You might also want to use strdup(), which is not specified in the
C standard but is available in every modern Unix system's C library.
And of course in the Unix (POSIX) system C library is also a family
of exec() functions. Learn to use "man -k", and also study a good
Unix programming text such as Kernighan & Pike.
It should also be noted that you shouldn't be writing programs that
run with elevated privilege (set-UID, daemon) without knowing a lot
more about security loopholes than you seem to be aware of.
"Douglas A. Gwyn" <DA****@null.net> writes: I *think* that what you are asking for is strcpy(), strcat(), etc. You might also want to use strdup(), which is not specified in the C standard but is available in every modern Unix system's C library. And of course in the Unix (POSIX) system C library is also a family of exec() functions. Learn to use "man -k", and also study a good Unix programming text such as Kernighan & Pike.
It should also be noted that you shouldn't be writing programs that run with elevated privilege (set-UID, daemon) without knowing a lot more about security loopholes than you seem to be aware of.
Since you mention security (e.g. buffer overflows),
it's worth adding that strcpy, strcat have long since
been deprecated in favor of strlcpy, strlcat.
-SEan
Sean Burke <fo****@mystery.org> wrote: Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
Not in ISO C, they haven't. Maybe in POSIX.
Richard
Sean Burke wrote: Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
If you think that helps very much with security
then you're much mistaken. Presumably the idea is
to prevent buffer overflows, but that can also be
done in many other ways, many of them involving
only the standard C library functions. And anyway
neither an unchecked failure to fill a buffer nor
an unchecked truncation of the contents of a buffer
is very good from the standpoint of security. It's
a big subject, and as usual the attempt to automate
correct programming just changes the symptoms of a
problem without curing the disease.
Sean Burke <fo****@mystery.org> writes: "Douglas A. Gwyn" <DA****@null.net> writes:
I *think* that what you are asking for is strcpy(), strcat(), etc. You might also want to use strdup(), which is not specified in the C standard but is available in every modern Unix system's C library. And of course in the Unix (POSIX) system C library is also a family of exec() functions. Learn to use "man -k", and also study a good Unix programming text such as Kernighan & Pike.
It should also be noted that you shouldn't be writing programs that run with elevated privilege (set-UID, daemon) without knowing a lot more about security loopholes than you seem to be aware of.
Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
I can't find those anywhere on my system, only strncpy and strncat.
The latter are defined by ISO C.
--
Måns Rullgård mr*@kth.se
In message <40***************@news.individual.net> of Fri, 13 Feb 2004
08:06:19 in comp.std.c, Richard Bos <rl*@hoekstra-uitgeverij.nl> writes Sean Burke <fo****@mystery.org> wrote:
Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
Not in ISO C, they haven't. Maybe in POSIX.
Neither there!
( http://www.opengroup.org/onlinepubs/.../string.h.html)
They ARE documented at http://www.courtesan.com/todd/papers/strlcpy.html
My summary of that is
size_t strlcpy(char *dst, const char *src, size_t size);
Copy a string of up to size-1 bytes from src to dst. Return strlen(src).
size_t strlcat(char *dst, const char *src, size_t size);
Concatenate bytes from src to dst to form a string with strlen(dst) <
size. Return strlen(dst) /* before concatenation */ + strlen(src).
The functions allow buffer overflow elimination.
For a pathological case given, strlcpy is slightly slower than strcpy
and much faster than strncpy because strncpy pads with nul bytes.
The authors added them to OpenBSD in 1996 and report their approval for
a future Solaris version in their undated paper. Source code is said to
be available at ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string
Have the functions been submitted for C standardisation?
--
Walter Briscoe
Walter Briscoe <wb******@ponle.demon.co.uk> wrote: In message <40***************@news.individual.net> of Fri, 13 Feb 2004 08:06:19 in comp.std.c, Richard Bos <rl*@hoekstra-uitgeverij.nl> writesSean Burke <fo****@mystery.org> wrote:
Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat. Not in ISO C, they haven't. Maybe in POSIX.
Neither there! (http://www.opengroup.org/onlinepubs/.../string.h.html)
They ARE documented at http://www.courtesan.com/todd/papers/strlcpy.html
My summary of that is size_t strlcpy(char *dst, const char *src, size_t size); Copy a string of up to size-1 bytes from src to dst. Return strlen(src).
size_t strlcat(char *dst, const char *src, size_t size); Concatenate bytes from src to dst to form a string with strlen(dst) < size. Return strlen(dst) /* before concatenation */ + strlen(src).
The functions allow buffer overflow elimination.
Nice, meaningless statement; so does strncat(), and so does using
strlen() and inserting a '\0' at the right place before using strcpy().
Have the functions been submitted for C standardisation?
No. Might be a nice addition, but I wouldn't describe them as vital.
Mind you, I won't complain if they _are_ added to C20XX.
Richard
Sean Burke <fo****@mystery.org> wrote in message news:<x7************@bolo.xenadyne.com>... "Douglas A. Gwyn" <DA****@null.net> writes:
I *think* that what you are asking for is strcpy(), strcat(), etc. You might also want to use strdup(), which is not specified in the C standard but is available in every modern Unix system's C library. And of course in the Unix (POSIX) system C library is also a family of exec() functions. Learn to use "man -k", and also study a good Unix programming text such as Kernighan & Pike.
It should also be noted that you shouldn't be writing programs that run with elevated privilege (set-UID, daemon) without knowing a lot more about security loopholes than you seem to be aware of.
Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
Have they?
They are not present in many frequently used operating systems.
They are not AFAIK part of the C standard, nor are they AFAIK part of
the POSIX standard.
In <x7************@bolo.xenadyne.com> Sean Burke <fo****@mystery.org> writes: Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
On the contrary, any C program using these identifiers with external
linkage invokes undefined behaviour.
Whoever wanted to improve upon strcpy and friends should have had enough
clues to avoid identifiers belonging to the implementation name space.
lstrcpy() and lstrcat() would have been ideal names for this purpose.
Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de Da*****@cern.ch (Dan Pop) writes: In <x7************@bolo.xenadyne.com> Sean Burke <fo****@mystery.org> writes:
Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
On the contrary, any C program using these identifiers with external linkage invokes undefined behaviour.
Maybe Mr. Burke misspelled "strncpy" and "strncat", mentioned in
ISO/IEC 9899:1999 under 7.21.2.4 and 7.21.3.2 ? Their prototypes (in
<string.h>) are
char *strncpy(char * restrict, const char * restrict, size_t);
char *strncat(char * restrict, const char * restrict, size_t);
--
Maurizio Loreti http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy ROT13: yb****@cq.vasa.vg
Maurizio Loreti <ml*@foobar.it> writes: Da*****@cern.ch (Dan Pop) writes:
In <x7************@bolo.xenadyne.com> Sean Burke <fo****@mystery.org> writes:
>Since you mention security (e.g. buffer overflows), >it's worth adding that strcpy, strcat have long since >been deprecated in favor of strlcpy, strlcat.
On the contrary, any C program using these identifiers with external linkage invokes undefined behaviour.
Maybe Mr. Burke misspelled "strncpy" and "strncat", mentioned in ISO/IEC 9899:1999 under 7.21.2.4 and 7.21.3.2 ? Their prototypes (in <string.h>) are
char *strncpy(char * restrict, const char * restrict, size_t); char *strncat(char * restrict, const char * restrict, size_t);
Maybe he meant those, but the non-standard strl* variants are more
useful. The return values from the standard str* functions are
utterly useless, since you already knew the value. Returning the
number bytes copied is much more useful. BTW, str*cat should be used
sparingly. In most cases you have, or can easily get (cheaper than
scanning), a pointer to the end of the destination string.
--
Måns Rullgård mr*@kth.se
Maurizio Loreti <ml*@foobar.it> writes: Da*****@cern.ch (Dan Pop) writes:
In <x7************@bolo.xenadyne.com> Sean Burke <fo****@mystery.org> writes:
Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
On the contrary, any C program using these identifiers with external linkage invokes undefined behaviour.
Maybe Mr. Burke misspelled "strncpy" and "strncat", mentioned in ISO/IEC 9899:1999 under 7.21.2.4 and 7.21.3.2 ? Their prototypes (in <string.h>) are
char *strncpy(char * restrict, const char * restrict, size_t); char *strncat(char * restrict, const char * restrict, size_t);
No, I meant strlcpy/strlcat, and I find them to be better
than the strn* calls. I'm astonished to learn that they
aren't yet standardised.
-SEan rl*@hoekstra-uitgeverij.nl (Richard Bos) writes: Walter Briscoe <wb******@ponle.demon.co.uk> wrote:
In message <40***************@news.individual.net> of Fri, 13 Feb 2004 08:06:19 in comp.std.c, Richard Bos <rl*@hoekstra-uitgeverij.nl> writesSean Burke <fo****@mystery.org> wrote:
> Since you mention security (e.g. buffer overflows), > it's worth adding that strcpy, strcat have long since > been deprecated in favor of strlcpy, strlcat.
Not in ISO C, they haven't. Maybe in POSIX.
Neither there! (http://www.opengroup.org/onlinepubs/.../string.h.html)
They ARE documented at http://www.courtesan.com/todd/papers/strlcpy.html
My summary of that is size_t strlcpy(char *dst, const char *src, size_t size); Copy a string of up to size-1 bytes from src to dst. Return strlen(src).
size_t strlcat(char *dst, const char *src, size_t size); Concatenate bytes from src to dst to form a string with strlen(dst) < size. Return strlen(dst) /* before concatenation */ + strlen(src).
The functions allow buffer overflow elimination.
Nice, meaningless statement; so does strncat(), and so does using strlen() and inserting a '\0' at the right place before using strcpy().
Have the functions been submitted for C standardisation?
No. Might be a nice addition, but I wouldn't describe them as vital. Mind you, I won't complain if they _are_ added to C20XX.
Don't tell me that snprintf, vsnprintf() are also nonstandard?
-SEan
Sean Burke wrote:
.... Don't tell me that snprintf, vsnprintf() are also nonstandard?
No: see sections 7.19.6.5 and 7.19.6.12.
In article <c0**********@sunnews.cern.ch>, Da*****@cern.ch (Dan Pop) writes: In <x7************@bolo.xenadyne.com> Sean Burke <fo****@mystery.org> writes:
Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
On the contrary, any C program using these identifiers with external linkage invokes undefined behaviour.
Whoever wanted to improve upon strcpy and friends should have had enough clues to avoid identifiers belonging to the implementation name space.
Presumably in at least some cases they could be provided by the
implementation, and in such a case programs using them would not
invoke UB, correct? This could potentially raise some tricky
questions about what is and what is not part of the implementation, I
suppose.
That said, I agree with the general point. An implementor has reason
to use a reserved identifier for a new function (it won't break
existing conforming code), but no one else does. I suppose someone
could argue that Miller and de Raadt were implementors when they
invented strlcpy and strlcat and added them to OpenBSD, since AFAICT
they added them directly to the standard library there, but their
choice of identifiers means non-implementors have to rename their
functions when porting them to other implementations.
--
Michael Wojcik mi************@microfocus.com
Pocket #9: A complete "artificial glen" with rocks, and artificial moon,
and forester's station. Excellent for achieving the effect of the
sublime without going out-of-doors. -- Joe Green
On Fri, 13 Feb 2004 10:19:47 +0000, Walter Briscoe wrote: They ARE documented at http://www.courtesan.com/todd/papers/strlcpy.html
My summary of that is size_t strlcpy(char *dst, const char *src, size_t size); Copy a string of up to size-1 bytes from src to dst. Return strlen(src).
size_t strlcat(char *dst, const char *src, size_t size); Concatenate bytes from src to dst to form a string with strlen(dst) < size. Return strlen(dst) /* before concatenation */ + strlen(src).
All the documentation, including the above, is laughable compared to
normal std. C text. Which is probably why there are a couple of different
implementations and the two major non OpenBSD implementations are
_documented_ to act differently than the OpenBSD versions do.
The functions allow buffer overflow elimination. For a pathological case given, strlcpy is slightly slower than strcpy and much faster than strncpy because strncpy pads with nul bytes.
IMO they are even more worthless than asprintf(), they are documented
to act differently on different platforms and (unlike asprintf() you can
still cause security issues due to truncation of data).
The authors added them to OpenBSD in 1996 and report their approval for a future Solaris version in their undated paper. Source code is said to be available at ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string
The "undated" paper has references to papers published in 1998, and says:
"The strlcpy() and strlcat() functions first appeared in OpenBSD 2.4."
....which dates them between May 19, and December 1, 1998. People
_started_ to hear of them after the 1999 Usenix when the paper... http://www.usenix.org/events/usenix9...rt/millert.pdf
....was presented, which even then as way too late for C99 ... and I don't
remember hearing about them until 2000 (which was after the last std. was
released).
--
James Antill -- ja***@and.org
Need an efficient and powerful string library for C? http://www.and.org/vstr/
On Fri, 13 Feb 2004 17:12:51 +0000, Sean Burke wrote: No, I meant strlcpy/strlcat, and I find them to be better than the strn* calls. I'm astonished to learn that they aren't yet standardised.
Not only are they not in std. C, they aren't available at all on any
of the major Linux variants. They also are/were implemented subtly
differently on Solaris.
You probably also want to read: http://www.and.org/vstr/security.html#alloc
--
James Antill -- ja***@and.org
Need an efficient and powerful string library for C? http://www.and.org/vstr/
James Antill <ja***********@and.org> writes: Not only are they not in std. C, they aren't available at all on any of the major Linux variants. They also are/were implemented subtly differently on Solaris.
They weren't implemented subtly different on Solaris; our implementation
is a straightforward clone from the original OpenBSD version and behaves
exactly the same.
You may be confused with "snprintf()" where Solaris originally
implemented it differently for "n = 0"; UNIX98 standardized
snprintf that it should return a value <= 0 for n = 0 and we're
a bit of a stickler for standards.
UNIX03 fixes that, fortunately, so the Solaris release will
have an snprintf which allows you to call it as follows:
size_t len = snprintf(0, NULL, .....);
to compute the length needed (note that snprintf can return
"-1" and set errno to EILSEQ.
Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
James Antill <ja***********@and.org> writes: All the documentation, including the above, is laughable compared to normal std. C text. Which is probably why there are a couple of different implementations and the two major non OpenBSD implementations are _documented_ to act differently than the OpenBSD versions do.
Please cite the specific differences between the implementations;
I don't know of any.
Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
On Sat, 14 Feb 2004 09:37:56 +0000, Casper H. S. Dik wrote: James Antill <ja***********@and.org> writes:
Not only are they not in std. C, they aren't available at all on any of the major Linux variants. They also are/were implemented subtly differently on Solaris.
They weren't implemented subtly different on Solaris; our implementation is a straightforward clone from the original OpenBSD version and behaves exactly the same.
That's what I would have expected, but I'd heard that they were
reimplemented to follow the "spec" and the return value was different in
the Solaris version[1].
I don't have access to a Solaris machine to check, and I apologize if
that wasn't the case.
[1] http://www.dwheeler.com/secure-progr...c.html#STRLCPY
--
James Antill -- ja***@and.org
Need an efficient and powerful string library for C? http://www.and.org/vstr/
James Antill <ja***********@and.org> writes: On Sat, 14 Feb 2004 09:41:31 +0000, Casper H. S. Dik wrote:
James Antill <ja***********@and.org> writes:
All the documentation, including the above, is laughable compared to normal std. C text. Which is probably why there are a couple of different implementations and the two major non OpenBSD implementations are _documented_ to act differently than the OpenBSD versions do.
Please cite the specific differences between the implementations; I don't know of any.
The "well known" one is the return value for strlcat(), see...
http://www.dwheeler.com/secure-progr...c.html#STRLCPY http://docs.sun.com/db/doc/806-0627/...indexterm-1028 http://docs.sun.com/db/doc/816-0213/...indexterm-1099
For the bogus "size = 0" case; you can't have a string that takes 0 bytes
of storage. I don't consider that a serious impediment to portable
programming because the strlcat with a size == 0 argument is something that
I do not expect to happen.
Any call of "strlcat(dst, src, len)" where strlen(dst) >= len is suspect
and I would call any results in that domain "unspecified" and certainly not
any obstacle to using the functions in portable programs. Certainly not
sufficient to give this fact that much attention.
Come to think of it, abort() is possibly the better way to handle this.
Strange that the Solaris source does reference beyond the "len" in dest
because I distinctly remember telling Theo and Todd about the OpenBSD source
doing the same when we were about to implement it in Solaris.
you can find this fact in the CVS commit history at: http://www.openbsd.org/cgi-bin/cvswe...ring/strlcat.c
rev 1.2
A case of "do as I say, not do as I do", I guess; I see about
getting us to follow suit.
Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
Richard Bos wrote: Sean Burke <fo****@mystery.org> wrote:
Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
Not in ISO C, they haven't. Maybe in POSIX.
Richard
I was introduced to them by someone who worked on *BSD platforms quite a
bit, and ended up writing equivalents of my own. This being a boring
afternoon, here's my implementation of strlcpy and strlcat. Comments most
likely lifted from *BSD sources as I am always too lazy to write them
myself. As everyone knows, my code *never* has any bugs :-)
strlcpy.c:
#include <stddef.h>
/*
* Copies src to string dst of size sz. sz is the full size of dst
* including the NUL character. At most sz-1 characters will be
* copied. Always NUL terminates dst, and doesn't fill dst with NULs
* like strncpy when sz > strlen(src). src *MUST* be a valid NUL
* terminated string.
*
* Returns strlen(src).
*
* If retval >= sz, truncation occurred.
*/
size_t strlcpy(char *dst, const char *src, size_t sz) {
register char *d = dst;
register const char *s = src;
register size_t n = sz;
if ( n ) {
--n;
while ( n && *s ) *d++ = *s++, --n;
*d = 0;
}
while ( *s++ );
return s - src - 1;
}
strlcat.c:
#include <stddef.h>
/*
* Appends src to string dst of size sz (unlike strncat, sz is the
* full size of dst, not space left). At most sz-1 characters will be
* copied. Always NUL terminates (unless sz <= strlen(dst)).
*
* Returns strlen(src) + MIN(sz, strlen(initial dst)).
*
* If retval >= sz, truncation occurred.
*/
size_t strlcat(char *dst, const char *src, size_t sz) {
register char *d = dst;
register const char *s = src;
register size_t n = sz;
if ( n ) {
--n;
while ( n && *d ) ++d, --n;
if ( n ) {
while ( n && *s ) *d++ = *s++, --n;
*d = 0;
}
n = d - dst + (*d != 0);
}
src = s;
while ( *s++ ) ;
return n + (s - src - 1);
}
-nrk.
--
Remove devnull for email
James Antill <ja***********@and.org> writes: On Fri, 13 Feb 2004 17:12:51 +0000, Sean Burke wrote:
No, I meant strlcpy/strlcat, and I find them to be better than the strn* calls. I'm astonished to learn that they aren't yet standardised.
Not only are they not in std. C, they aren't available at all on any of the major Linux variants. They also are/were implemented subtly differently on Solaris.
You probably also want to read:
http://www.and.org/vstr/security.html#alloc
An excellent summary of the reasons why strlcpy/cat are valuable.
I don't think availability is much of a problem either, since the
OpenBSD implementations are:
- Free as in beer
- Free as in speech
- A whopping 30 lines of code apiece.
-SEan
nrk wrote: * ... Always NUL terminates dst, ...
Not when sz==0.
* .... src *MUST* be a valid NUL terminated string.
It doesn't need to be. It must point to at least sz-1
bytes and is terminated by the first 0-valued byte.
If this stuff is supposed to be used for safety-critical
programming, its interface specification should be
accurate. Also, once you fix it up you should see that
both example functions have behavior that is relatively
complicated to describe, which makes it relatively
difficult to use in provably correct algorithms.
It would be much better if a function either completes
a simply described task or else does nothing and reports
failure.
Douglas A. Gwyn wrote: nrk wrote: * ... Always NUL terminates dst, ... Not when sz==0.
When sz == 0, there is no space to put the terminating NUL. I think that's
sort of self-evident :-) * .... src *MUST* be a valid NUL terminated string.
It doesn't need to be. It must point to at least sz-1 bytes and is terminated by the first 0-valued byte.
From the relevant code:
register const char *s = src;
...
while ( *s++ );
Seems to me that nasal demons shall fly if src is not NUL terminated. Or
are you saying the specification needs to be changed? What am I missing?
The whole point is that you could send a src string that's larger than your
destination, in which case the copy is still safe, but the return value
tells you that truncation occurred.
If this stuff is supposed to be used for safety-critical programming, its interface specification should be accurate. Also, once you fix it up you should see that both example functions have behavior that is relatively complicated to describe, which makes it relatively difficult to use in provably correct algorithms.
The only questionably difficult interface is strlcat. But the difficult
situation shouldn't arise in "well-behaved" programs (it happens when you
pass in a size for the destination that is <= strlen(destination)). As for
correctness, you can guarantee that the functions will:
a) Never write more than what you specify in the sz parameter
b) Result in NUL terminated dst (with the exception above)
c) Clearly report truncation whenever it occurs
It would be much better if a function either completes a simply described task or else does nothing and reports failure.
These are supposed to be analogous to strncpy and strncat. Under those
circumstances, I am not sure what failure means. My guess is that it's up
to the user to determine what constitutes failure and what actions to take.
Hence the design that says we'll do our best and tell the user that not
everything was ok. It's upto the user to decide then what to do with that
information. IMHO these functions (not particularly my implementations
though) are quite well thought out and well designed. They do report
"failure" (assuming that means truncation), simply and quite effectively.
I don't understand why you would bother with functional specifications of
what they do to dst when you are solely interested in distinguishing
"failure" and "success".
-nrk.
--
Remove devnull for email
In <c0*********@enews1.newsguy.com> mw*****@newsguy.com (Michael Wojcik) writes: In article <c0**********@sunnews.cern.ch>, Da*****@cern.ch (Dan Pop) writes: In <x7************@bolo.xenadyne.com> Sean Burke <fo****@mystery.org> writes:
>Since you mention security (e.g. buffer overflows), >it's worth adding that strcpy, strcat have long since >been deprecated in favor of strlcpy, strlcat. On the contrary, any C program using these identifiers with external linkage invokes undefined behaviour.
Whoever wanted to improve upon strcpy and friends should have had enough clues to avoid identifiers belonging to the implementation name space.
Presumably in at least some cases they could be provided by the implementation, and in such a case programs using them would not invoke UB, correct?
Wrong. Calling such a function *unconditionally* invokes undefined
behaviour.
This could potentially raise some tricky questions about what is and what is not part of the implementation, I suppose.
For the purpose of our discussion, it is enough that the function in
question is not part of the standard C library.
An implementation is free to provide such a function as an extension
without having its conformance affected, but *any* code using it invokes
undefined behaviour.
Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de mw*****@newsguy.com (Michael Wojcik) wrote in message news:<c0*********@enews1.newsguy.com>... In article <c0**********@sunnews.cern.ch>, Da*****@cern.ch (Dan Pop) writes: In <x7************@bolo.xenadyne.com> Sean Burke <fo****@mystery.org> writes:
Since you mention security (e.g. buffer overflows), it's worth adding that strcpy, strcat have long since been deprecated in favor of strlcpy, strlcat.
On the contrary, any C program using these identifiers with external linkage invokes undefined behaviour.
Whoever wanted to improve upon strcpy and friends should have had enough clues to avoid identifiers belonging to the implementation name space.
Presumably in at least some cases they could be provided by the implementation, and in such a case programs using them would not invoke UB, correct? This could potentially raise some tricky
You need to be careful when you read the standard, it contains many
pieces of technical jargon which are defined by the standard itself to
mean something not quite the same as the ordinary english definition.
This is one example. "undefined behavior" doesn't mean "behavior that
is undefined"; it's a piece of technical jargon used by the C
standard, which roughly means "behavior that is not defined by the C
standard".
The behavior of such code remains UB even if the implementation
chooses to provide it's own definition. UB includes, as one of it's
literal infinity of possibilities, behaving exactly as the
implementation has defined it to behave.
In article <8b**************************@posting.google.com >, ku****@wizard.net (James Kuyper) writes: mw*****@newsguy.com (Michael Wojcik) wrote in message news:<c0*********@enews1.newsguy.com>... Presumably in at least some cases they could be provided by the implementation, and in such a case programs using them would not invoke UB, correct? You need to be careful when you read the standard, it contains many pieces of technical jargon which are defined by the standard itself to mean something not quite the same as the ordinary english definition. This is one example. "undefined behavior" doesn't mean "behavior that is undefined"; it's a piece of technical jargon used by the C standard, which roughly means "behavior that is not defined by the C standard".
Right. I understood that...
The behavior of such code remains UB even if the implementation chooses to provide it's own definition. UB includes, as one of it's literal infinity of possibilities, behaving exactly as the implementation has defined it to behave.
....but missed this bit when I glanced over the Standard before posting
that message. I somehow got the impression that if the implementation
provided additional str* functions (with external linkage), a program
running under that implementation could invoke them without causing UB.
Which doesn't make much sense, now that I think about it.
(Thanks also to Dan for posting a similar correction.)
--
Michael Wojcik mi************@microfocus.com
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
-- David Bonde
Brian Inglis <Br**********@SystematicSw.Invalid> writes: On Fri, 13 Feb 2004 17:12:51 GMT in comp.std.c, Sean Burke <fo****@mystery.org> wrote:
Maurizio Loreti <ml*@foobar.it> writes:
Da*****@cern.ch (Dan Pop) writes:
> In <x7************@bolo.xenadyne.com> Sean Burke <fo****@mystery.org> writes: > > >Since you mention security (e.g. buffer overflows), > >it's worth adding that strcpy, strcat have long since > >been deprecated in favor of strlcpy, strlcat. You mispelled n as noted below. On the contrary, any C program using these identifiers with external > linkage invokes undefined behaviour.
Maybe Mr. Burke misspelled "strncpy" and "strncat", mentioned in ISO/IEC 9899:1999 under 7.21.2.4 and 7.21.3.2 ? Their prototypes (in <string.h>) are
char *strncpy(char * restrict, const char * restrict, size_t); char *strncat(char * restrict, const char * restrict, size_t);
No, I meant strlcpy/strlcat, and I find them to be better than the strn* calls. I'm astonished to learn that they aren't yet standardised.
You must be one of those Pascal types who like to access strings as character arrays with indices, instead of pointers as K&R intended. You wouldn't have liked BCPL, B, or NB either! ;^>
The BSD string functions strl{cat,cpy} are unlikely to be standardised as they aren't supported by many libraries, and don't fit with any of the current string handling functions, except strspn() and strcspn(), which are also not heavily advertised or used, as their names are confusing, nondescriptive, unobvious, and they too return counts instead of pointers.
In any case, I prefer to check my string lengths before I do anything with strcpy(); strncpy()'s handy for clearing previous junk from buffers; never need strcat(), as I like to know where I am, and going to be in a buffer. Avoids buffer overflows, heap and stack overwrites, SIGSEGV, ACCVIO, and other unpleasantries, don't ya know.
I'm not sure why you've revived this long-dormant thread.
As far as factual matters go, I recall that the upshot of
the discussion was that:
1. strcpy/strcat have not been formally deprecated in the
C standard
2. strlcpy/strlcat have not been incorporated into the
C standard
As far as matters of preference go, if you find strncpy/ncat
adequate for your needs, that's great. I agree that strlen()
alone is sufficient to avoid overflows with strcpy/cat, as
long as you are careful.
I find that code using strlcpy/lcat is cleaner and less
susceptible to error, but YMMV.
Oh, and as for strspn, strcspn - I find these are very useful
functions, but it's another example of the power of idiom in
programming. It took me a long time to notice that I could
this, for example:
if (strspn(argv[i], "-0123456789") != strlen(argv[i]))
fprintf(stderr, "The argument \"%s\" must be a decimal integer.\n", argv[i]);
-SEan
Brian Inglis wrote:
.... snip ... The BSD string functions strl{cat,cpy} are unlikely to be standardised as they aren't supported by many libraries, and don't fit with any of the current string handling functions, except strspn() and strcspn(), which are also not heavily advertised or used, as their names are confusing, nondescriptive, unobvious, and they too return counts instead of pointers.
Which (return values) is precisely why they should be used in
preference to the already available standard routines. They
greatly reduce the prevalence of errors. They are also easily
implemented with purely standard C and no library dependencies, so
there is no reason to eschew them. For one implementation (put in
public domain) see:
<http://cbfalconer.home.att.net/download/strlcpy.zip>
For justifications for their use, etc, see:
<http://www.courtesan.com/todd/papers/strlcpy.html>
If your system has these routines, congratulations. If not, feel
free to mount mine. In either case using them will reduce your
error rate.
--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Sean Burke <fo****@mystery.org> writes:
[...] Oh, and as for strspn, strcspn - I find these are very useful functions, but it's another example of the power of idiom in programming. It took me a long time to notice that I could this, for example:
if (strspn(argv[i], "-0123456789") != strlen(argv[i])) fprintf(stderr, "The argument \"%s\" must be a decimal integer.\n", argv[i]);
[code reformatted to fit screen]
That's fine if you consider "3-2", "---", and "" to be decimal integers.
--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
# > if (strspn(argv[i], "-0123456789") != strlen(argv[i]))
# > fprintf(stderr,
# > "The argument \"%s\" must be a decimal integer.\n",
# > argv[i]);
#
# [code reformatted to fit screen]
#
# That's fine if you consider "3-2", "---", and "" to be decimal integers.
if (strtol(p,&q,0), p==q) not an integer
else if (*q) integer followed by something else
else an integer
--
Derk Gwen http://derkgwen.250free.com/html/index.html
We found a loophole; they can't keep us out anymore.
Derk Gwen <de******@HotPOP.com> writes: # > if (strspn(argv[i], "-0123456789") != strlen(argv[i])) # > fprintf(stderr, # > "The argument \"%s\" must be a decimal integer.\n", # > argv[i]); # # [code reformatted to fit screen] # # That's fine if you consider "3-2", "---", and "" to be decimal integers.
if (strtol(p,&q,0), p==q) not an integer else if (*q) integer followed by something else else an integer
Anyone who knows how to use strtol doesn't need advice from me. :-)
But how many people just pass the argument to atoi() and let any
problems manifest themselves further along?
I think the method I illustrated has the virtue of being a
"pretty good" filter, while also being much more widely
applicable than strtol().
Suppose I want to accept an IP address, but I want to ensure
that it's not a domain name:
if (strspn(argv[i], ".0123456789") != strlen(argv[i]))
fprintf(stderr, "Arg \"%s\" must be an numeric IP address.\n", argv[i]);
Sure, "...0" would pass this filter, but the chief goal is
to reject "foo.bar.com". Yes, I could use inet_addr() instead,
but what does inet_addr() do with "9.37.190.192.in-addr.arpa"?
Certainly, regcomp/regexec provide a filtering method that can
be both precise and very general. But strspn/cspn() provide a
useful balance of precision and convenience.
-SEan
Derk Gwen <de******@HotPOP.com> writes: # > if (strspn(argv[i], "-0123456789") != strlen(argv[i])) # > fprintf(stderr, # > "The argument \"%s\" must be a decimal integer.\n", # > argv[i]); # # [code reformatted to fit screen] # # That's fine if you consider "3-2", "---", and "" to be decimal integers.
if (strtol(p,&q,0), p==q) not an integer else if (*q) integer followed by something else else an integer
Anyone who knows how to use strtol doesn't need advice from me. :-)
But how many people just pass the argument to atoi() and let any
problems manifest themselves further along?
I think the method I illustrated has the virtue of being a
"pretty good" filter, while also being much more widely
applicable than strtol().
Suppose I want to accept an IP address, but I want to ensure
that it's not a domain name:
if (strspn(argv[i], ".0123456789") != strlen(argv[i]))
fprintf(stderr, "Arg \"%s\" must be an numeric IP address.\n", argv[i]);
Sure, "...0" would pass this filter, but the chief goal is
to reject "foo.bar.com". Yes, I could use inet_addr() instead,
but what does inet_addr() do with "9.37.190.192.in-addr.arpa"?
Certainly, regcomp/regexec provide a filtering method that can
be both precise and very general. But strspn/cspn() provide a
useful balance of precision and convenience.
-SEan
>>> Sean Burke wrote:
SB> Sure, "...0" would pass this filter, but the chief goal is
SB> to reject "foo.bar.com". Yes, I could use inet_addr() instead,
SB> but what does inet_addr() do with "9.37.190.192.in-addr.arpa"?
$ host 127.0.0.1
1.0.0.127.IN-ADDR.ARPA domain name pointer localhost
$ ping 1.0.0.127.in-addr.arpa
ping: cannot resolve 1.0.0.127.in-addr.arpa: No address associated with name
Feel the difference between asking A and PTR ;)
-netch- This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Jonas Galvez |
last post by:
Is it true that joining the string elements of a list is faster than
concatenating them via the '+' operator?
"".join()
vs
'a'+'b'+'c'
If so, can anyone explain why?
|
by: hagai26 |
last post by:
I am looking for the best and efficient way to replace the first word
in a str, like this:
"aa to become" -> "/aa/ to become"
I know I can use spilt and than join them
but I can also use regular...
|
by: John Ford |
last post by:
For simple string concatenation, is there a difference between...
Dim s As String
s += "add this to string"
....and...
Dim s As String
s = String.Concat(s, "add this to string")
|
by: Justin M. Keyes |
last post by:
Hi,
Please read carefully before assuming that this is the same old
question about string concatenation in C#!
It is well-known that the following concatenation produces multiple
immutable...
|
by: Mark A. Sam |
last post by:
Hello,
I am having a problem with imputting into a string variable:
Dim strSQL As String = "INSERT INTO tblContactForm1 (txtName, txtCompany,
txtPhone, txtEmail, txtComment, chkGrower,...
|
by: genc_ymeri |
last post by:
Hi over there,
Propably this subject is discussed over and over several times. I did google
it too but I was a little bit surprised what I read on internet when it
comes 'when to use what'.
Most...
|
by: Richard Lewis Haggard |
last post by:
I thought that the whole point of StringBuilder was that it was supposed to
be a faster way of building strings than string. However, I just put
together a simple little application to do a...
|
by: Larry Hastings |
last post by:
This is such a long posting that I've broken it out into sections.
Note that while developing this patch I discovered a Subtle Bug
in CPython, which I have discussed in its own section below.
...
|
by: =?Utf-8?B?RWxlbmE=?= |
last post by:
I am surprised to discover that c# automatically converts an integer to a
string when concatenating with the "+" operator. I thought c# was supposed
to be very strict about types. Doesn't it seem...
|
by: raylopez99 |
last post by:
StringBuilder better and faster than string for adding many strings.
Look at the below. It's amazing how much faster StringBuilder is than
string.
The last loop below is telling: for adding...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: tracyyun |
last post by:
Hello everyone,
I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
|
by: giovanniandrean |
last post by:
The energy model is structured as follows and uses excel sheets to give input data:
1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
|
by: NeoPa |
last post by:
Hello everyone.
I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report).
I know it can be done by selecting :...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
|
by: Teri B |
last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course.
0ne-to-many. One course many roles.
Then I created a report based on the Course form and...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
|
by: isladogs |
last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, Mike...
|
by: GKJR |
last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...
| |