By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,646 Members | 1,175 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,646 IT Pros & Developers. It's quick & easy.

Needed APIs: For copying file and finding Disk Usage

P: n/a
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

Dec 5 '06 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Sankar wrote:
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>

Dec 5 '06 #2

P: n/a
On Mon, 04 Dec 2006 18:01:09 -0800, Sankar wrote:
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

Dec 5 '06 #3

P: n/a
Sankar wrote:
>
.... 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.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 5 '06 #4

P: n/a
William Ahern <wi*****@25thandClement.comwrites:
On Mon, 04 Dec 2006 18:01:09 -0800, Sankar wrote:
>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>

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 5 '06 #5

P: n/a
Sankar wrote:
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.

--
Simon.
Dec 5 '06 #6

P: n/a

Sankar wrote:
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
--
Lew

Dec 5 '06 #7

P: n/a
Simon Biber <ne**@ralmin.ccwrites:
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 5 '06 #8

P: n/a
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
William Ahern <wi*****@25thandClement.comwrites:
>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);
}
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

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
--
Posted via a free Usenet account from http://www.teranews.com

Dec 5 '06 #9

P: n/a
"Stephen Sprunk" <st*****@sprunk.orgwrites:
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
>William Ahern <wi*****@25thandClement.comwrites:
>>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);
}

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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 5 '06 #10

P: n/a
"Stephen Sprunk" <st*****@sprunk.orgwrites:
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.
--
"Welcome to the wonderful world of undefined behavior, where the demons
are nasal and the DeathStation users are nervous." --Daniel Fox
Dec 5 '06 #11

P: n/a
Stephen Sprunk wrote:
>
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
William Ahern <wi*****@25thandClement.comwrites:
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);
}

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.

--
pete
Dec 6 '06 #12

P: n/a
On Tue, 05 Dec 2006 05:54:38 +0000, Keith Thompson wrote:
<snip>
>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 ;)
>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);
}
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
Dec 6 '06 #13

This discussion thread is closed

Replies have been disabled for this discussion.