variadic function calling variadic function

Discussion in 'C Programming' started by goldfita@signalsguru.net, May 3, 2006.

  1. Guest

    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;
    }
     
    , May 3, 2006
    #1
    1. Advertising

  2. Michael Mair Guest

    schrieb:
    > 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
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, May 3, 2006
    #2
    1. Advertising

  3. Guest

    Michael Mair wrote:
    <snip>

    >
    > http://c-faq.com/varargs/ , especially 15.5 and 15.6
    >
    > -Michael
    > --
    > E-Mail: Mine is an /at/ gmx /dot/ de address.


    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.
     
    , May 3, 2006
    #3
  4. Chris Torek Guest

    In article <>
    <> wrote:
    >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).
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, May 3, 2006
    #4
  5. Flash Gordon Guest

    wrote:
    > Michael Mair wrote:
    > <snip>
    >
    >> http://c-faq.com/varargs/ , especially 15.5 and 15.6
    >>
    >> -Michael
    >> --
    >> E-Mail: Mine is an /at/ gmx /dot/ de address.

    >
    > 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.
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc
     
    Flash Gordon, May 3, 2006
    #5
  6. Guest

    Flash Gordon wrote:
    > wrote:
    > > Michael Mair wrote:
    > > <snip>
    > >
    > >> http://c-faq.com/varargs/ , especially 15.5 and 15.6
    > >>
    > >> -Michael
    > >> --
    > >> E-Mail: Mine is an /at/ gmx /dot/ de address.

    > >
    > > 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.
    > --
    > Flash Gordon, living in interesting times.
    > Web site - http://home.flash-gordon.me.uk/
    > comp.lang.c posting guidelines and intro:
    > http://clc-wiki.net/wiki/Intro_to_clc



    For some reason the vprintf/printf thing wasn't clicking. The last two
    posts put me on the right track. Thanks.
     
    , May 3, 2006
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andreas Lagemann
    Replies:
    8
    Views:
    486
    Mike Wahler
    Jan 10, 2005
  2. Colin Walters
    Replies:
    2
    Views:
    526
    Ben Pfaff
    Feb 13, 2004
  3. Ross A. Finlayson
    Replies:
    19
    Views:
    604
    Keith Thompson
    Mar 10, 2005
  4. Replies:
    2
    Views:
    351
    Dave Thompson
    Feb 27, 2006
  5. Replies:
    8
    Views:
    324
    red floyd
    Jun 20, 2007
Loading...

Share This Page