Needed APIs: For copying file and finding Disk Usage

S

Sankar

Dear all,
I am programming in Linux , wherein I need to know a couple of
things.

1) Does an API exist that can copy file onto another file ( an API
equivalent of 'cp') ?


2) Is there an API that tells me the disk usage ( equivalent for
cmdline
'du' ) ?


Any pointers would be greatly appreciated.


Thanks n
 
S

santosh

Sankar said:
Dear all,
I am programming in Linux , wherein I need to know a couple of
things.

1) Does an API exist that can copy file onto another file ( an API
equivalent of 'cp') ?

2) Is there an API that tells me the disk usage ( equivalent for
cmdline
'du' ) ?

Any pointers would be greatly appreciated.

Please try posting to comp.os.linux.* comp.unix.programmer etc.

Also see the link below to try to find what you want:
<http://www.gnu.org/software/libc/manual/html_node/index.html>
 
C

CBFalconer

Sankar said:
.... snip ...

1) Does an API exist that can copy file onto another file ( an API
equivalent of 'cp') ?

#include <stdio.h>
int main(void) {
int ch;
while (EOF != (ch = getchar())) putchar(ch);
return 0;
}

copies stdin to stdout.
2) Is there an API that tells me the disk usage ( equivalent for
cmdline 'du' ) ?

No. Standard C knows nothing about disks or the usage thereof.
 
S

Simon Biber

Sankar said:
Dear all,
I am programming in Linux , wherein I need to know a couple of
things.

If the operating system is relevant then it's probably not a question
that can be answered within standard C. In particular system calls or
APIs such that you're asking for are not defined by C.
1) Does an API exist that can copy file onto another file ( an API
equivalent of 'cp') ?

Not exactly, but you can write this one in standard C:

int cp(const char *source, const char *dest)
{
FILE *ifp = fopen(source, "rb");
FILE *ofp = fopen(dest, "wb");
int ch;
if(!ifp || !ofp) return -1;
while((ch = getc(ifp)) != EOF) putc(ch, ofp);
if(ferror(ifp) || ferror(ofp)) return -1;
if(fclose(ifp) || fclose(ofp)) return -1;
return 0;
}
2) Is there an API that tells me the disk usage ( equivalent for
cmdline
'du' ) ?

No - this cannot be done in standard C. There are two choices: one is to
find a system-specific function you can call (OT: man statfs). The other
is to use the 'system' function to run your 'du' program through the
command line. If you redirect its output to a file you can then read
that file and parse it.
 
W

William Ahern

Dear all,
I am programming in Linux , wherein I need to know a couple of
things.

1) Does an API exist that can copy file onto another file ( an API
equivalent of 'cp') ?

The following isn't guaranteed, I believe, by any ISO C standard to work,
per se (though it's difficult to discern exactly what you're asking), but
within the domain of Unix platforms/implementations (including Linux) the
unspecified parts are specified and implemented so:

#include <stdio.h>
/* FILE fopen(3) fread(3) fwrite(3) feof(3) fflush(3) */

#include <stdlib.h>
/* EXIT_FAILURE exit(3) */

int main(void) {

FILE *src, *dst;
unsigned char buf[1024];
size_t n;

if (0 == (src = fopen("/path/to/source/file", "r")))
perror("fopen"), exit(EXIT_FAILURE);

if (0 == (dst = fopen("/path/to/sink/file", "w")))
perror("fopen"), exit(EXIT_FAILURE);

while (0 < (n = fread(buf, 1, sizeof buf, src))) {
if (n != fwrite(buf, 1, n, dst))
perror("fwrite"), exit(EXIT_FAILURE);
}

if (!feof(src))
perror("fread"), exit(EXIT_FAILURE);

if (0 != fflush(dst))
perror("fflush"), exit(EXIT_FAILURE);

return 0;

}

2) Is there an API that tells me the disk usage ( equivalent for cmdline
'du' ) ?

You need to ask in a Linux-specific forum.

- Bill
 
K

Keith Thompson

William Ahern said:
Dear all,
I am programming in Linux , wherein I need to know a couple of
things.

1) Does an API exist that can copy file onto another file ( an API
equivalent of 'cp') ?

The following isn't guaranteed, I believe, by any ISO C standard to work,
per se (though it's difficult to discern exactly what you're asking), but
within the domain of Unix platforms/implementations (including Linux) the
unspecified parts are specified and implemented so:

#include <stdio.h>
/* FILE fopen(3) fread(3) fwrite(3) feof(3) fflush(3) */

#include <stdlib.h>
/* EXIT_FAILURE exit(3) */

int main(void) {

FILE *src, *dst;
unsigned char buf[1024];

Why 1024? It would probably make more sense to use BUFSIZ.
size_t n;

if (0 == (src = fopen("/path/to/source/file", "r")))
perror("fopen"), exit(EXIT_FAILURE);

This is an awkward use of the comma operator, IMHO. I'd write:

if ((src = fopen("/path/to/source/file", "r")) == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}

Note that the standard doesn't guarantee that fopen() sets errno.
if (0 == (dst = fopen("/path/to/sink/file", "w")))
perror("fopen"), exit(EXIT_FAILURE);

while (0 < (n = fread(buf, 1, sizeof buf, src))) {
if (n != fwrite(buf, 1, n, dst))
perror("fwrite"), exit(EXIT_FAILURE);
}

if (!feof(src))
perror("fread"), exit(EXIT_FAILURE);

if (0 != fflush(dst))
perror("fflush"), exit(EXIT_FAILURE);

return 0;

}

Assuming that "cp" is an OS command that copies files (yeah, I know it
is, but this is comp.lang.c), it's likely to do a number of
system-specific things to optimize performance. If you don't mind a
Linux- or Unix-specific solution, you might consider invoking the "cp"
command itself via system(). <OT>The cp command does a number of
things that you can't do in portable C, as you can see by reading the
man page.</OT>
 
L

Lew Pitcher

Sankar said:
Dear all,
I am programming in Linux , wherein I need to know a couple of
things.

1) Does an API exist that can copy file onto another file ( an API
equivalent of 'cp') ?

Sort of. There is a standard C function that will permit you to pass a
string argument to the "command processor to be executed in a manner
which the implementation shall document". This means that you /could/
system("cp fromfile tofile");
and "copy file onto another file" in a manner exactly the same as the
Unix cp(1) command.
2) Is there an API that tells me the disk usage ( equivalent for
cmdline 'du' ) ?

Similarly, the system() function can invoke the du(1) command, but as
system() doesn't return the output of the command, you'll have to do
some trickery.
system("du >some.file");
followed by
FILE *diskusage = fopen("some.file", "r");
(with the appropriate error checking everywhere, of course)
This will tell you the disk usage /exactly/ as du(1) would.

HTH
 
K

Keith Thompson

Simon Biber said:
Sankar wrote: [...]
2) Is there an API that tells me the disk usage ( equivalent for
cmdline
'du' ) ?

No - this cannot be done in standard C. There are two choices: one is
to find a system-specific function you can call (OT: man statfs). The
other is to use the 'system' function to run your 'du' program through
the command line. If you redirect its output to a file you can then
read that file and parse it.

And if your system has the "du" command, it probably has a
system-specific function that lets a C program read the output of a
command without writing it to a temporary file. Which is why this is
a question for comp.unix.programmer, where the function in question is
topical.
 
S

Stephen Sprunk

Keith Thompson said:
This is an awkward use of the comma operator, IMHO. I'd write:

if ((src = fopen("/path/to/source/file", "r")) == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}

It's awkward, yes, but still legal. It's also the only use I've found
for the comma operator other than incrementing multiple variables in a
"for" construct.

The problem is that many folks will not notice it's a comma (expecting a
semicolon), or will think it's a typo. That leads to maintenance
problems. It's also not done widely enough to be considered idiomatic,
so I wouldn't use it in an example for a newbie, but I use it in my own
code now and then.

For instance, I once had to change several hundred "close(fd);"
statements to also do "fd=-1;". Since most, but not all of them, were
bare statements underneath an if, the simplest way was a simple
find-and-replace with "close(fd), fd=-1;" Not clean, and I'm not proud
of it, but it worked perfectly and saved me a lot of time.

You'll also see it in macros now and then, as a way to avoid needing the
"do {...} while (0)" trick. It's debatable which construction is worse,
but as long as it's confined to macros most people won't comment.

S
 
K

Keith Thompson

Stephen Sprunk said:
It's awkward, yes, but still legal. It's also the only use I've found
for the comma operator other than incrementing multiple variables in a
"for" construct.

Yes, I agree that it's perfectly legal.
The problem is that many folks will not notice it's a comma (expecting
a semicolon), or will think it's a typo. That leads to maintenance
problems. It's also not done widely enough to be considered
idiomatic, so I wouldn't use it in an example for a newbie, but I use
it in my own code now and then.

For instance, I once had to change several hundred "close(fd);"
statements to also do "fd=-1;". Since most, but not all of them, were
bare statements underneath an if, the simplest way was a simple
find-and-replace with "close(fd), fd=-1;" Not clean, and I'm not
proud of it, but it worked perfectly and saved me a lot of time.

Well, I never write bare statements under an if (I always use braces,
even for a single statement), but like all style questions that's
largely a matter of taste.
You'll also see it in macros now and then, as a way to avoid needing
the "do {...} while (0)" trick. It's debatable which construction is
worse, but as long as it's confined to macros most people won't
comment.

The "do {...} while (0)" trick is IMHO ugly, but it's a common idiom
and there's often no other way to achieve the same goal. Using comma
operators to avoid it seems reasonable to me.
 
B

Ben Pfaff

Stephen Sprunk said:
For instance, I once had to change several hundred "close(fd);"
statements to also do "fd=-1;". Since most, but not all of them, were
bare statements underneath an if, the simplest way was a simple
find-and-replace with "close(fd), fd=-1;" Not clean, and I'm not
proud of it, but it worked perfectly and saved me a lot of time.

C has a construct called "functions" that can be usefully applied
to reduce duplication. For example:

void
my_close (int *fd)
{
close (*fd);
*fd = 1;
}

Then, later, when you want to check whether the fd is -1 before
closing it, you only have to change one place.
 
P

pete

Stephen said:
It's awkward, yes, but still legal. It's also the only use I've found
for the comma operator other than incrementing multiple variables in a
"for" construct.

The problem is that many folks
will not notice it's a comma (expecting a
semicolon), or will think it's a typo. That leads to maintenance
problems.
It's also not done widely enough to be considered idiomatic,
so I wouldn't use it in an example for a newbie,
but I use it in my own code now and then.

I always use a compound statement in my if statements.
For instance, I once had to change several hundred "close(fd);"
statements to also do "fd=-1;". Since most, but not all of them, were
bare statements underneath an if, the simplest way was a simple
find-and-replace with "close(fd), fd=-1;"
Not clean, and I'm not proud
of it, but it worked perfectly and saved me a lot of time.

That's most of the reason why
I always use a compound statement with an if, or an else, or a loop.
You'll also see it in macros now and then,
as a way to avoid needing the
"do {...} while (0)" trick.
It's debatable which construction is worse,
but as long as it's confined to macros most people won't comment.

I use comma style macros whenever I can.

#define SWAP(A, B, T) \
((void)(*(T) = *(A), *(A) = *(B), *(B) = *(T)))

If the macro needs to contain statements
which are not expression statements, then I can't.
 
W

William Ahern

On Tue, 05 Dec 2006 05:54:38 +0000, Keith Thompson wrote:
FILE *src, *dst;
unsigned char buf[1024];

Why 1024? It would probably make more sense to use BUFSIZ.

Yes. However, I didn't have my copy of the standard at-hand, and figured
I'd rather take the lashing for not using it, rather than to use it but
document it's source incorrectly ;)
This is an awkward use of the comma operator, IMHO. I'd write:

if ((src = fopen("/path/to/source/file", "r")) == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}

I often use the comma operator like so

if (some_arg == 0)
return (errno = EINVAL), -1;

because I'm trying to express that I'm returning a particular state, not
simply doing a series of actions and then returning a value.

I carried it over to the example, but I agree that the example code is a
awkward. Neither the former (perror()) nor latter (exit()) action
in the expression strictly follows the pattern I use when employing the
comma operator in that situation. I suppose I was simply trying to be
terse
 

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,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top