variadic function calling variadic function

G

goldfita

I'm not sure if I'm doing something stupid, or if I'm not understanding
how to use variadic functions. These functions appear to be working
individually. In ast_call, I can vprintf the argument list and it
looks fine. If I invoke write_cmd, it seems to work fine. But when I
invoke write_cmd in ast_call with argp, I get garbage in argp in
write_cmd. I don't know where it's breaking.

int ast_call(struct ast_connection *conn, char *msg, ...)
{
va_list argp;

va_start(argp,msg);
if(!write_cmd(conn->socket,msg,argp)) {
va_end(argp);
return write_FAIL;
}
va_end(argp);
if(!conn->params.wait_for_resp)
return AST_SUCCESS;
return ast_wait_peek_by_id(conn,conn->cnt++);
}

static int write_cmd(int socket, char *msg, ...)
{
int n=0,len=0,slen;
va_list argp;
char buf[BUFSIZE];

va_start(argp,msg);
vsprintf(buf,msg,argp);
va_end(argp);
slen = strlen(buf);
puts(buf);
for(len=0; len<slen;) {
if((n = write(socket,buf+len,slen-len)) < 0)
return 0;
len += n;
}
return 1;
}
 
M

Michael Mair

I'm not sure if I'm doing something stupid, or if I'm not understanding
how to use variadic functions. These functions appear to be working
individually. In ast_call, I can vprintf the argument list and it
looks fine. If I invoke write_cmd, it seems to work fine. But when I
invoke write_cmd in ast_call with argp, I get garbage in argp in
write_cmd. I don't know where it's breaking.

int ast_call(struct ast_connection *conn, char *msg, ...)
{
va_list argp;

va_start(argp,msg);
if(!write_cmd(conn->socket,msg,argp)) {
va_end(argp);
return write_FAIL;
}
va_end(argp);
if(!conn->params.wait_for_resp)
return AST_SUCCESS;
return ast_wait_peek_by_id(conn,conn->cnt++);
}

static int write_cmd(int socket, char *msg, ...)
{
int n=0,len=0,slen;
va_list argp;
char buf[BUFSIZE];

va_start(argp,msg);
vsprintf(buf,msg,argp);
va_end(argp);
slen = strlen(buf);
puts(buf);
for(len=0; len<slen;) {
if((n = write(socket,buf+len,slen-len)) < 0)
return 0;
len += n;
}
return 1;
}

http://c-faq.com/varargs/ , especially 15.5 and 15.6

-Michael
 
G

goldfita

Michael Mair wrote:
http://c-faq.com/varargs/ , especially 15.5 and 15.6

-Michael

Isn't that what I'm doing? I don't understand what 15.6 has to do with
my problem. I called

va_start(argp,msg);
vsprintf(buf,msg,argp);
va_end(argp);


and

va_start(argp,msg);
if(!write_cmd(conn->socket,msg,argp)) {
va_end(argp);
return write_FAIL;
}
va_end(argp);

I'm just not seeing it. It must be obvious to someone. Thanks.
 
C

Chris Torek

I'm not sure if I'm doing something stupid, or if I'm not understanding
how to use variadic functions.

Michael Mair already pointed you at the FAQ entry. I will add
a few more remarks here:
... In ast_call, I can vprintf the argument list and it
looks fine.

Note, you are calling vprintf(), not printf(), when it "works fine".
If I invoke write_cmd [directly], it seems to work fine.

Here you are calling printf-- er, I mean write_cmd(), not vprintf--
oops, I mean vwrite_cmd().
But when I invoke write_cmd in ast_call ...

You need to call vwrite_cmd().

Of course, you first need to *write* vwrite_cmd(). This is easy
since you already have all the appropriate code:
static int write_cmd(int socket, char *msg, ...)
{
int n=0,len=0,slen;
va_list argp;
char buf[BUFSIZE];

va_start(argp,msg);
vsprintf(buf,msg,argp);
va_end(argp);
slen = strlen(buf);
puts(buf);
for(len=0; len<slen;) {
if((n = write(socket,buf+len,slen-len)) < 0)
return 0;
len += n;
}
return 1;
}

Change the ", ..." part to take a "va_list" argument, stop calling
va_start and va_end (since you already have the va_list), and leave
the rest of the code as-is. Then rewrite write_cmd() in terms of
a call to vwrite_cmd() (to eliminate redundancy and thus improve
maintainability, and incidentally save code space too).
 
F

Flash Gordon

Michael Mair wrote:


Isn't that what I'm doing? I don't understand what 15.6 has to do with
my problem. I called

va_start(argp,msg);
vsprintf(buf,msg,argp);
va_end(argp);


and

va_start(argp,msg);
if(!write_cmd(conn->socket,msg,argp)) {
va_end(argp);
return write_FAIL;
}
va_end(argp);

I'm just not seeing it. It must be obvious to someone. Thanks.

Michael did not point you at the most appropriate question, which is 15.12

He possibly expected you to work it out from how vsprintf works.
 

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,780
Messages
2,569,608
Members
45,242
Latest member
KendrickKo

Latest Threads

Top