subroutine in c

Discussion in 'C Programming' started by rudra, Apr 18, 2010.

  1. rudra

    rudra Guest

    I have 2 subroutine in c(which is ultimately called by fortran):
    $ cat bit_unm.c
    /***********************************************
    This code returns the machine bit
    to the program bitinit
    ***********************************************/
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    int operating_system(char *sys) {
    FILE *stream;
    char *sysptr;
    int bit;
    sysptr = &sys[0];
    sys[0] = 0x0;
    stream = popen("/bin/uname -snm", "r");
    fread(sysptr, 1, 32, stream);
    pclose(stream);
    return bit;
    }

    and$ cat nis.c
    /***********************************************
    This code returns the machine bit
    to the program bitinit
    ***********************************************/
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    int operating_sys(char *nis ){
    FILE *stream;
    char *sysptr;
    int bit;
    sysptr = &nis[0];
    nis[6] = 0x0;
    stream=popen("/bin/nisdomainname","r");
    fread(sysptr,1,15,stream);
    pclose(stream);
    return bit;
    }

    As it is seen this two are doing almost same thing except the unix
    command in popen.
    is it possible to make it a single routine where the unix command
    nisdomainname or uname will be an argument?
     
    rudra, Apr 18, 2010
    #1
    1. Advertising

  2. rudra <> wrote:
    > I have 2 subroutine in c(which is ultimately called by fortran):
    > $ cat bit_unm.c
    > /***********************************************
    > This code returns the machine bit
    > to the program bitinit
    > ***********************************************/
    > #include <stdlib.h>
    > #include <stdio.h>
    > #include <string.h>


    > int operating_system(char *sys) {
    > FILE *stream;
    > char *sysptr;
    > int bit;


    This is an uninitialized variable that has some random value.

    > sysptr = &sys[0];
    > sys[0] = 0x0;


    Why do you go through all of this? Using the pointer you
    received would do quite well (and setting the first ele-
    ment of the array pointed is good for nothing).

    > stream = popen("/bin/uname -snm", "r");
    > fread(sysptr, 1, 32, stream);


    What you read from popen() won't contain a trailing '\0',
    so what the caller receives isn't a string (and the caller
    has no means of finding out how many characters got read
    if the stuff returned by popen() doesn't have a trailing
    '\n', e.g. in the case that what '/bin/uname' returnsed
    is longer than 32 characters (including the '\n' at the
    end). Also please note that popen() (and pclose()) isn't
    a standard C function (even though it is declared in
    <stdio.h> on POSIX compliant system).

    A slightly safer version would be

    fscanf( stream, "%31[^\n]", sys );

    assuming that what 'sys' points to has enough room for
    32 chars. While the result won't contain a trailing '\n'
    it will have a '\0', so it's a proper string no matter
    what popen() returns.

    > pclose(stream);
    > return bit;


    And here you return the random value 'bit' is set to. What
    is that supposed to be good for?

    > }


    > and$ cat nis.c
    > /***********************************************
    > This code returns the machine bit
    > to the program bitinit
    > ***********************************************/
    > #include <stdlib.h>
    > #include <stdio.h>
    > #include <string.h>
    > int operating_sys(char *nis ){
    > FILE *stream;
    > char *sysptr;
    > int bit;
    > sysptr = &nis[0];
    > nis[6] = 0x0;


    Setting the 7th element of the array to '\0' looks
    even more weird than setting the first one in the
    other function;-)

    > stream=popen("/bin/nisdomainname","r");
    > fread(sysptr,1,15,stream);
    > pclose(stream);
    > return bit;
    > }


    > As it is seen this two are doing almost same thing except the unix
    > command in popen.


    Yes, with the difference that what gets returned from
    /bin/nisdomainname may have even less characters to give
    the caller a chance to figure out what really was returned.

    > is it possible to make it a single routine where the unix command
    > nisdomainname or uname will be an argument?


    Yes, of course, just pass it to popen() as the first argument
    instead of the hard-coded string you pass it now (assuming
    that the complete command with options is passed to the
    function, otherwise you have to either use another string and
    do some string-splicing to get the complete command or use
    strcmp() to figure out what to call).

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Apr 18, 2010
    #2
    1. Advertising

  3. rudra

    Uno Guest

    Jens Thoms Toerring wrote:
    > rudra <> wrote:
    >> I have 2 subroutine in c(which is ultimately called by fortran):
    >> $ cat bit_unm.c
    >> /***********************************************
    >> This code returns the machine bit
    >> to the program bitinit
    >> ***********************************************/
    >> #include <stdlib.h>
    >> #include <stdio.h>
    >> #include <string.h>

    >
    >> int operating_system(char *sys) {
    >> FILE *stream;
    >> char *sysptr;
    >> int bit;

    >
    > This is an uninitialized variable that has some random value.
    >
    >> sysptr = &sys[0];
    >> sys[0] = 0x0;

    >
    > Why do you go through all of this? Using the pointer you
    > received would do quite well (and setting the first ele-
    > ment of the array pointed is good for nothing).
    >
    >> stream = popen("/bin/uname -snm", "r");
    >> fread(sysptr, 1, 32, stream);

    >
    > What you read from popen() won't contain a trailing '\0',
    > so what the caller receives isn't a string (and the caller
    > has no means of finding out how many characters got read
    > if the stuff returned by popen() doesn't have a trailing
    > '\n', e.g. in the case that what '/bin/uname' returnsed
    > is longer than 32 characters (including the '\n' at the
    > end). Also please note that popen() (and pclose()) isn't
    > a standard C function (even though it is declared in
    > <stdio.h> on POSIX compliant system).
    >
    > A slightly safer version would be
    >
    > fscanf( stream, "%31[^\n]", sys );
    >
    > assuming that what 'sys' points to has enough room for
    > 32 chars. While the result won't contain a trailing '\n'
    > it will have a '\0', so it's a proper string no matter
    > what popen() returns.
    >
    >> pclose(stream);
    >> return bit;

    >
    > And here you return the random value 'bit' is set to. What
    > is that supposed to be good for?
    >
    >> }

    >
    >> and$ cat nis.c
    >> /***********************************************
    >> This code returns the machine bit
    >> to the program bitinit
    >> ***********************************************/
    >> #include <stdlib.h>
    >> #include <stdio.h>
    >> #include <string.h>
    >> int operating_sys(char *nis ){
    >> FILE *stream;
    >> char *sysptr;
    >> int bit;
    >> sysptr = &nis[0];
    >> nis[6] = 0x0;

    >
    > Setting the 7th element of the array to '\0' looks
    > even more weird than setting the first one in the
    > other function;-)
    >
    >> stream=popen("/bin/nisdomainname","r");
    >> fread(sysptr,1,15,stream);
    >> pclose(stream);
    >> return bit;
    >> }

    >
    >> As it is seen this two are doing almost same thing except the unix
    >> command in popen.

    >
    > Yes, with the difference that what gets returned from
    > /bin/nisdomainname may have even less characters to give
    > the caller a chance to figure out what really was returned.
    >
    >> is it possible to make it a single routine where the unix command
    >> nisdomainname or uname will be an argument?

    >
    > Yes, of course, just pass it to popen() as the first argument
    > instead of the hard-coded string you pass it now (assuming
    > that the complete command with options is passed to the
    > function, otherwise you have to either use another string and
    > do some string-splicing to get the complete command or use
    > strcmp() to figure out what to call).


    I thought I'd try to follow along on this one. I don't know what OP
    intends, but this was as close as I could come to divining it:

    $ gcc -D_GNU_SOURCE -std=c99 -Wall -Wextra r1.c -o out
    $ ./out
    sys is Linux dan-desktop i686
    $ cat r1.c
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    int main(void)
    {
    FILE *stream;
    char *sys;
    sys = malloc(100);
    stream = popen("/bin/uname -snm", "r");
    fscanf( stream, "%31[^\n]", sys );
    printf("sys is %s\n", sys);
    pclose(stream);
    return 0;
    }

    // gcc -D_GNU_SOURCE -std=c99 -Wall -Wextra r1.c -o out
    $

    Question: With this input as an example, what is happening in that
    fscanf line?
    --
    Uno
     
    Uno, Apr 19, 2010
    #3
  4. On 18 Apr, 18:29, rudra <> wrote:
    > I have 2 subroutine in c(which is ultimately called by fortran):
    > $ cat bit_unm.c
    > /***********************************************
    >  This code returns the machine bit
    >  to the program bitinit
    >  ***********************************************/
    > #include <stdlib.h>
    > #include <stdio.h>
    > #include <string.h>
    >
    > int operating_system(char *sys) {
    >     FILE *stream;
    >     char *sysptr;
    >     int bit;
    >     sysptr = &sys[0];
    >     sys[0] = 0x0;
    >     stream = popen("/bin/uname -snm", "r");
    >     fread(sysptr, 1, 32, stream);
    >     pclose(stream);
    >     return bit;
    >
    > }


    bearing Jens's remarks in mind... Is this any help

    int operating_system(char *sys, const char *cmd)
    {
    FILE *stream;
    char *sysptr;
    int bit;
    sysptr = &sys[0];
    sys[0] = 0x0;
    stream = popen (cmd, "r");
    fread (sysptr, 1, 32, stream);
    pclose (stream);
    return bit;
    }
     
    Nick Keighley, Apr 19, 2010
    #4
  5. Uno <> wrote:
    > I thought I'd try to follow along on this one. I don't know what OP
    > intends, but this was as close as I could come to divining it:


    > $ gcc -D_GNU_SOURCE -std=c99 -Wall -Wextra r1.c -o out
    > $ ./out
    > sys is Linux dan-desktop i686
    > $ cat r1.c
    > #include <stdlib.h>
    > #include <stdio.h>
    > #include <string.h>


    > int main(void)
    > {
    > FILE *stream;
    > char *sys;
    > sys = malloc(100);
    > stream = popen("/bin/uname -snm", "r");
    > fscanf( stream, "%31[^\n]", sys );
    > printf("sys is %s\n", sys);
    > pclose(stream);
    > return 0;
    > }


    > // gcc -D_GNU_SOURCE -std=c99 -Wall -Wextra r1.c -o out
    > $


    > Question: With this input as an example, what is happening in that
    > fscanf line?


    I guess you mean the "%31[^\n]" bit? It stands for "read up
    to 31 characters but stop if you find a '\n' character". A
    simple

    fscanf( stream, "%31s", sys );

    wouldn't do here since it would already stop at the first
    white-space character, and of "Linux dan-desktop i686" only
    the first word, "Linux", would be read in. By using "[^\n]"
    instead of "s" fscanf() is asked to continue reading while
    there's no '\n' found in the input - you can specify a set
    of characters to accept (or reject when the list starts
    with a '^') within the square braces. And the '31' is, of
    course, there to keep fscanf() from reading more than 31
    chars (the 32nd is the trailing '\0' it automatically ap-
    pends). Of course, in your example, where there's room for
    100 chars in 'sys' you could use "99[^\n]" instead, but in
    the OP's case it looked as if there was only room for 32.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Apr 19, 2010
    #5
  6. rudra

    Uno Guest

    Nick Keighley wrote:
    > On 18 Apr, 18:29, rudra <> wrote:
    >> I have 2 subroutine in c(which is ultimately called by fortran):
    >> $ cat bit_unm.c
    >> /***********************************************
    >> This code returns the machine bit
    >> to the program bitinit
    >> ***********************************************/
    >> #include <stdlib.h>
    >> #include <stdio.h>
    >> #include <string.h>
    >>
    >> int operating_system(char *sys) {
    >> FILE *stream;
    >> char *sysptr;
    >> int bit;
    >> sysptr = &sys[0];
    >> sys[0] = 0x0;
    >> stream = popen("/bin/uname -snm", "r");
    >> fread(sysptr, 1, 32, stream);
    >> pclose(stream);
    >> return bit;
    >>
    >> }

    >
    > bearing Jens's remarks in mind... Is this any help
    >
    > int operating_system(char *sys, const char *cmd)
    > {
    > FILE *stream;
    > char *sysptr;
    > int bit;
    > sysptr = &sys[0];
    > sys[0] = 0x0;
    > stream = popen (cmd, "r");
    > fread (sysptr, 1, 32, stream);
    > pclose (stream);
    > return bit;
    > }
    >
    >


    This might be worse, Nick. He only needs one char *. If anything is
    read, then
    sys[0] = 0x0;
    is overwritten.

    The return of bit is guaranteed to have no useful information. The name
    of bit is wrong-headed, as what bit is significant in his call to uname,
    which you cut out.

    What were you intending with cmd?
    --
    Uno
     
    Uno, Apr 19, 2010
    #6
  7. Uno <> wrote:
    > Nick Keighley wrote:
    > > int operating_system(char *sys, const char *cmd)
    > > {
    > > FILE *stream;
    > > char *sysptr;
    > > int bit;
    > > sysptr = &sys[0];
    > > sys[0] = 0x0;
    > > stream = popen (cmd, "r");
    > > fread (sysptr, 1, 32, stream);
    > > pclose (stream);
    > > return bit;
    > > }


    > This might be worse, Nick. He only needs one char *.


    <snip>

    > What were you intending with cmd?


    Answering the OPs question of

    | As it is seen this two are doing almost same thing except the unix
    | command in popen.
    | is it possible to make it a single routine where the unix command
    | nisdomainname or uname will be an argument?

    I would presume.
    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Apr 19, 2010
    #7
  8. On 19 Apr, 19:52, Uno <> wrote:
    > Nick Keighley wrote:
    > > On 18 Apr, 18:29, rudra <> wrote:


    > >> I have 2 subroutine in c(which is ultimately called by fortran):
    > >> $ cat bit_unm.c
    > >> /***********************************************
    > >>  This code returns the machine bit
    > >>  to the program bitinit
    > >>  ***********************************************/
    > >> #include <stdlib.h>
    > >> #include <stdio.h>
    > >> #include <string.h>

    >
    > >> int operating_system(char *sys) {
    > >>     FILE *stream;
    > >>     char *sysptr;
    > >>     int bit;
    > >>     sysptr = &sys[0];
    > >>     sys[0] = 0x0;
    > >>     stream = popen("/bin/uname -snm", "r");
    > >>     fread(sysptr, 1, 32, stream);
    > >>     pclose(stream);
    > >>     return bit;

    >
    > >> }

    >
    > > bearing Jens's remarks in mind... Is this any help

    >
    > > int operating_system(char *sys, const char *cmd)
    > > {
    > >     FILE *stream;
    > >     char *sysptr;
    > >     int bit;
    > >     sysptr = &sys[0];
    > >     sys[0] = 0x0;
    > >     stream = popen (cmd, "r");
    > >     fread (sysptr, 1, 32, stream);
    > >     pclose (stream);
    > >     return bit;
    > > }


    this was done in a hurry as i was about to catch a bus. I passed a
    parameter into the original code. I didn't fix all the bugs in the
    original code hence "bearing Jens's remarks in mind". To fix the code
    properly involved too much mind reading and knowledge of arcane bits
    of unix.

    > This might be worse, Nick.  


    why?


    > He only needs one char *.  


    I thought system[] was an "out" parameter and cmd[] an "in", to abuse
    Ada terminology.

    > If anything is read, then
    > sys[0] = 0x0;
    > is overwritten.
    > The return of bit is guaranteed to have no useful information.


    this was all covered by Jen's post


    > The name of bit is wrong-headed, as what bit is significant in his call to uname,
    > which you cut out.


    see excuses section at the beginning


    > What were you intending with cmd?


    OP:
    "is it possible to make it a single routine where the unix command
    nisdomainname or uname will be an argument?"


    --
    "It is a good rule in life never to apologize. The right sort of
    people do not want apologies, and the wrong sort take a mean
    advantage from them." - P. G. Wodehouse
     
    Nick Keighley, Apr 20, 2010
    #8
  9. rudra

    Uno Guest

    Nick Keighley wrote:


    > this was all covered by Jen's post


    He's not Jen. He's Jens. I think it's acceptable to create the
    possessive as Jens's or Jens', but I'm no English grammarian.

    > this was done in a hurry as i was about to catch a bus. I passed a
    > parameter into the original code. I didn't fix all the bugs in the
    > original code hence "bearing Jens's remarks in mind". To fix the code
    > properly involved too much mind reading and knowledge of arcane bits
    > of unix.


    >> The name of bit is wrong-headed, as what bit is significant in his call to uname,
    >> which you cut out.

    >
    > see excuses section at the beginning


    I'm glad you're socially responsible enough to use public
    transportation. What makes the long waits bearable? A good fortran, c,
    or unix reference book.

    rudra never resurfaced, so la dee frickin da. I think that's a little
    rude of rudra.
    --
    Uno
     
    Uno, Apr 22, 2010
    #9
  10. On 22 Apr, 06:55, Uno <> wrote:
    > Nick Keighley wrote:


    > > this was all covered by Jen's post

    >
    > He's not Jen.  He's Jens.  I think it's acceptable to create the
    > possessive as Jens's or Jens', but I'm no English grammarian.


    you are quite right (and I have no excuses this time). "Jens's" I
    believe, "Jens'" if it were a plural.

    >  > this was done in a hurry as i was about to catch a bus.


    [...]

    > I'm glad you're socially responsible enough to use public
    > transportation.  What makes the long waits bearable?  A good fortran, c,
    > or unix reference book.


    Scheme at the moment or downloaded BBC World Service
     
    Nick Keighley, Apr 22, 2010
    #10
    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. Casey
    Replies:
    3
    Views:
    871
    Casey
    Jan 30, 2004
  2. Hon Seng Phuah
    Replies:
    1
    Views:
    484
    Jürgen Exner
    Mar 5, 2004
  3. Gunnar Hjalmarsson

    Subroutine definition

    Gunnar Hjalmarsson, Jun 11, 2004, in forum: Perl
    Replies:
    2
    Views:
    621
    Jim Gibson
    Jun 17, 2004
  4. Mark
    Replies:
    0
    Views:
    498
  5. king
    Replies:
    5
    Views:
    205
Loading...

Share This Page