string concatenation

S

Shri

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
 
M

Mark A. Odell

(e-mail address removed) (Shri) wrote in

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.
 
D

Douglas A. Gwyn

Shri said:
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.
 
S

Sean Burke

Douglas A. Gwyn said:
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
 
R

Richard Bos

Sean Burke said:
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
 
D

Douglas A. Gwyn

Sean said:
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.
 
?

=?iso-8859-1?q?M=E5ns_Rullg=E5rd?=

Sean Burke said:
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.
 
W

Walter Briscoe

In message said:
Not in ISO C, they haven't. Maybe in POSIX.

Neither there!
(http://www.opengroup.org/onlinepubs/007904975/basedefs/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?
 
R

Richard Bos

Walter Briscoe said:
Neither there!
(http://www.opengroup.org/onlinepubs/007904975/basedefs/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
 
R

Rob Thorpe

Sean Burke said:
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.
 
D

Dan Pop

In said:
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
 
M

Maurizio Loreti

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);
 
?

=?iso-8859-1?q?M=E5ns_Rullg=E5rd?=

Maurizio Loreti said:
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.
 
S

Sean Burke

Maurizio Loreti said:
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
 
S

Sean Burke

Nice, meaningless statement; so does strncat(), and so does using
strlen() and inserting a '\0' at the right place before using strcpy().


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
 
M

Michael Wojcik

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 (e-mail address removed)

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
 
J

James Antill

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
 
J

James Antill

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/usenix99/full_papers/millert/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).
 
C

Casper H.S. Dik

James Antill said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top