subroutine in c

R

rudra

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?
 
J

Jens Thoms Toerring

rudra said:
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
 
U

Uno

Jens said:
rudra said:
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?
 
N

Nick Keighley

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;
}
 
J

Jens Thoms Toerring

Uno said:
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
 
U

Uno

Nick said:
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?
 
J

Jens Thoms Toerring

Uno said:
Nick said:
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 *.

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
 
N

Nick Keighley

Nick said:
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?"
 
U

Uno

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.

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

Nick Keighley

Nick Keighley wrote:

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
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,159
Latest member
SweetCalmCBDGummies
Top