more tweaking, for future expansion
Here is a better replacement of my earlier do_fd_copy. This one can take an
array of input and output file descriptors, and uses select to do its work.
Usefull for execing, and redirecting ALL of stdin, stdout, and stderr.
===
diff -ruN dpkg-1.6.3.2.orig/include/dpkg.h.in dpkg-1.6.3.2/include/dpkg.h.in
--- dpkg-1.6.3.2.orig/include/dpkg.h.in Fri Dec 24 05:49:11 1999
+++ dpkg-1.6.3.2/include/dpkg.h.in Sat Dec 25 03:53:33 1999
@@ -199,6 +199,7 @@
void waitsubproc(pid_t pid, const char *description, int sigpipeok);
int do_fd_copy(int fd1, int fd2, char *desc);
+int do_fd_copy_array(int fdread[], int fdwrite[], int length, char *desc);
extern volatile int onerr_abort;
diff -ruN dpkg-1.6.3.2.orig/lib/mlib.c dpkg-1.6.3.2/lib/mlib.c
--- dpkg-1.6.3.2.orig/lib/mlib.c Fri Dec 24 05:48:51 1999
+++ dpkg-1.6.3.2/lib/mlib.c Sat Dec 25 03:34:40 1999
@@ -123,12 +123,15 @@
checksubprocerr(status,description,sigpipeok);
}
-int do_fd_copy(int fd1, int fd2, char *desc) {
- char *buf, *sbuf;
- int count;
+int do_fd_copy_array(int fdread[], int fdwrite[], int length, char *desc) {
+ char *buf, *sbuf, *sbuf2, *sbuf3;
+ int count, count2, ret, idx, maxfd;
+ fd_set readset, readsetsave;
+
char *er_msg_1 = _("failed to allocate buffer for copy (%s)");
char *er_msg_2 = _("failed in copy on write (%s)");
char *er_msg_3 = _("failed in copy on read (%s)");
+ char *er_msg_4 = _("failed in copy, write != read (%s)");
count = strlen(er_msg_1) + strlen(desc) + 1;
sbuf = malloc(count);
@@ -142,27 +145,53 @@
ohshite(sbuf);
free(sbuf);
- count = strlen(er_msg_2) + strlen(desc) + 1;
- sbuf = malloc(count);
- if(sbuf == NULL)
+ if((sbuf = malloc(count = strlen(er_msg_2) + strlen(desc) + 1)) == NULL)
ohshite(_("failed to allocate buffer for snprintf 2"));
snprintf(sbuf, count, er_msg_2, desc);
sbuf[count-1] = 0;
- while((count = read(fd1, buf, 32768)) > 0)
- if(write(fd2, buf, count) < count)
- ohshite(sbuf);
-
+ if((sbuf2 = malloc(count = strlen(er_msg_3) + strlen(desc) + 1)) == NULL)
+ ohshite(_("failed to allocate buffer for snprintf 3"));
+ snprintf(sbuf2, count, er_msg_3, desc);
+ sbuf2[count-1] = 0;
+
+ if((sbuf3 = malloc(count = strlen(er_msg_4) + strlen(desc) + 1)) == NULL)
+ ohshite(_("failed to allocate buffer for snprintf 4"));
+ snprintf(sbuf3, count, er_msg_4, desc);
+ sbuf3[count-1] = 0;
+
+ FD_ZERO(&readset);
+ for(idx = 0; idx < length; idx++) {
+ FD_SET(fdread[idx], &readset);
+ FD_SET(fdread[idx], &readsetsave);
+ if(fdread[idx] > maxfd)
+ maxfd = fdread[idx];
+ }
+ while((ret = select(maxfd + 1, &readset, NULL, NULL, 0)) > 0) {
+ for(idx = 0; idx < length; idx++) {
+ if(FD_ISSET(fdread[idx], &readset)) {
+ if((count = read(fdread[idx], buf, 32768)) < 0)
+ ohshite(sbuf2);
+ if((count2 = write(fdwrite[idx], buf, count)) < 0)
+ ohshite(sbuf);
+ if(count2 != count)
+ ohshite(sbuf3);
+ }
+ }
+ FD_ZERO(&readset);
+ readset = readsetsave;
+ }
free(sbuf);
- count = strlen(er_msg_3) + strlen(desc) + 1;
- sbuf = malloc(count);
- if(sbuf == NULL)
- ohshite(_("failed to allocate buffer for snprintf 2"));
- snprintf(sbuf, count, er_msg_3, desc);
- sbuf[count-1] = 0;
+ free(sbuf2);
+ free(sbuf3);
- if(count < 0)
- ohshite(_("failed in copy on read (control)"));
- free(sbuf);
free(buf);
+}
+
+int do_fd_copy(int fd1, int fd2, char *desc) {
+
+ int fdread[1], fdwrite[1];
+ fdread[0] = fd1;
+ fdwrite[0] = fd2;
+ return do_fd_copy_array(fdread, fdwrite, 1, desc);
}
===
----BEGIN GEEK CODE BLOCK----
Version: 3.12
GCS d- s: a-- c+++ UL++++ P+ L++++ !E W+ M o+ K- W--- !O M- !V PS--
PE++ Y+ PGP++ t* 5++ X+ tv b+ D++ G e h*! !r z?
-----END GEEK CODE BLOCK-----
----BEGIN PGP INFO----
Adam Heath <doogie@debian.org> Finger Print | KeyID
67 01 42 93 CA 37 FB 1E 63 C9 80 1D 08 CF 84 0A | DE656B05 PGP
AD46 C888 F587 F8A3 A6DA 3261 8A2C 7DC2 8BD4 A489 | 8BD4A489 GPG
-----END PGP INFO-----
Reply to: