aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--copy/copy.c145
1 files changed, 60 insertions, 85 deletions
diff --git a/copy/copy.c b/copy/copy.c
index d943aaa..f88efc2 100644
--- a/copy/copy.c
+++ b/copy/copy.c
@@ -34,7 +34,6 @@
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
-#include <poll.h>
#include <stdlib.h>
#include <sys/stat.h>
@@ -42,6 +41,13 @@
#define O_BINARY 0
#endif
+#ifdef WIN32
+#define open _open
+#define close _close
+#define fdopen _fdopen
+#define fdclose _fdclose
+#endif
+
#define CONSOLE_PREFIX "[copy]: "
typedef struct _copy
@@ -53,7 +59,7 @@ t_copy;
t_class *copy_class;
-int copy(const char *source, const char *target);
+static int do_copy(const char *source, const char *target);
void *copy_new(t_symbol *s, int argc, t_atom *argv)
{
@@ -63,10 +69,11 @@ void *copy_new(t_symbol *s, int argc, t_atom *argv)
return (void *)x;
}
-void copy_list(t_copy *x, t_symbol *s, int ac, t_atom *av)
+static void copy_list(t_copy *x, t_symbol *s, int ac, t_atom *av)
{
char source[MAXPDSTRING];
char target[MAXPDSTRING];
+ int rv;
if(ac != 2 || (av[0].a_type != A_SYMBOL && av[1].a_type != A_SYMBOL))
{
@@ -76,7 +83,7 @@ void copy_list(t_copy *x, t_symbol *s, int ac, t_atom *av)
atom_string(&av[0], source, MAXPDSTRING);
atom_string(&av[1], target, MAXPDSTRING);
- int rv = copy(source, target);
+ rv = do_copy(source, target);
rv++;
if(rv)
@@ -96,110 +103,78 @@ void copy_setup(void)
class_addlist(copy_class, copy_list);
}
-void block(int fd, int event)
-{
- struct pollfd topoll;
- topoll.fd = fd;
- topoll.events = event;
- poll(&topoll, 1, -1);
- // no need to check errors - if the stream is bust then the
- // next read/write will tell us
-}
-int copy_data_buffer(int fdin, int fdout, void *buf, size_t bufsize)
+static int copy_data(FILE *source, FILE *target)
{
- for(;;)
- {
- void *pos;
- // read data to buffer
- ssize_t bytestowrite = read(fdin, buf, bufsize);
- if (bytestowrite == 0) break; // end of input
- if (bytestowrite == -1)
- {
- if (errno == EINTR) continue; // signal handled
- if (errno == EAGAIN)
- {
- block(fdin, POLLIN);
- continue;
- }
- return -1;
- }
-
- // write data from buffer
- pos = buf;
- while (bytestowrite > 0)
- {
- ssize_t bytes_written = write(fdout, pos, bytestowrite);
- if (bytes_written == -1)
- {
- if (errno == EINTR) continue;
- if (errno == EAGAIN)
- {
- block(fdout, POLLOUT);
- continue;
- }
- return -1;
- }
- bytestowrite -= bytes_written;
- pos += bytes_written;
- }
- }
- return 0;
-}
+ char buffer[BUFSIZ];
+ size_t n;
-#ifndef FILECOPY_BUFFER_SIZE
-#define FILECOPY_BUFFER_SIZE (64*1024)
-#endif
-
-int copy_data(int fdin, int fdout)
-{
- for (size_t bufsize = FILECOPY_BUFFER_SIZE; bufsize >= 256; bufsize /= 2)
+ while ((n = fread(buffer, sizeof(char), sizeof(buffer), source)) > 0)
{
- void *buffer = malloc(bufsize);
- if (buffer != NULL)
- {
- int result = copy_data_buffer(fdin, fdout, buffer, bufsize);
- free(buffer);
- return result;
- }
+ if (fwrite(buffer, sizeof(char), n, target) != n)
+ {
+ error("write failed");
+ return -1;
+ }
}
- return -1;
+ return 0;
}
-int copy(const char *source, const char *target)
-{
- struct stat info;
- int fdin = open(source, O_RDONLY|O_BINARY, 0);
- if (fdin == -1)
- {
+static int do_copy(const char *source, const char *target)
+{
+ struct stat info;
+ int rv;
+ int rv2;
+ int fdtarget;
+ int fdsource;
+ FILE *fsource;
+ FILE *ftarget;
+
+ fdsource = open(source, O_RDONLY|O_BINARY, 0);
+
+ if (fdsource == -1)
+ {
error(CONSOLE_PREFIX "invalid input");
return -1;
}
-
- int rv = fstat(fdin, &info);
-
+
+ rv = fstat(fdsource, &info);
+
if(rv == -1)
{
error(CONSOLE_PREFIX "stat failed\n");
return -1;
}
-
- int fdout = open(target, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, info.st_mode);
- if (fdout == -1)
- {
+
+ fdtarget = open(target, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, info.st_mode);
+
+ if (fdtarget == -1)
+ {
error(CONSOLE_PREFIX "invalid output\n");
- close(fdin);
+ close(fdsource);
return -1;
- }
+ }
- rv = copy_data(fdin, fdout);
+ fsource = fdopen(fdsource, "rb");
+ ftarget = fdopen(fdtarget, "wb");
+
+ rv = copy_data(fsource, ftarget);
if (rv == -1)
{
- error(CONSOLE_PREFIX "copy failed\n");
+ error(CONSOLE_PREFIX "copy failed");
}
- return 0;
+ rv = fclose(fsource);
+ rv2 = fclose(ftarget);
+
+ if (rv || rv2)
+ {
+ error(CONSOLE_PREFIX "file close failed");
+ rv = -1;
+ }
+
+ return rv;
}