MCPcopy Create free account
hub / github.com/GJDuck/e9patch / emitPatch

Function emitPatch

src/e9patch/e9emit.cpp:68–272  ·  view source on GitHub ↗

* Emit a binary patch. Implements (an approximation of) the pipeline: * cat bin1 | xxd > tmp.1 * cat bin2 | xxd > tmp.2 * diff tmp.1 tmp.2 | gzip > filename * rm tmp.1 tmp.2 */

Source from the content-addressed store, hash-verified

66 * rm tmp.1 tmp.2
67 */
68void emitPatch(const char *filename, const char *compress, int fd1,
69 const uint8_t *bin2, size_t len2)
70{
71 char fifo_name1[64], fifo_name2[64], *fifo_name = nullptr;
72 int fd, fds2[2], fds3[2];
73 static unsigned CHILD_MAX = 4;
74 pid_t pids[CHILD_MAX];
75 const char *progs[CHILD_MAX];
76 unsigned pc = 0;
77 uint64_t rand64[2];
78
79 // Create named pipes:
80 fd = open("/dev/urandom", O_RDONLY);
81 if (fd < 0)
82 error("failed to open \"/dev/urandom\": %s", strerror(errno));
83 if (read(fd, (void *)rand64, sizeof(rand64)) != sizeof(rand64))
84 error("failed to read from \"/dev/urandom\": %s", strerror(errno));
85 close(fd);
86 pid_t pid = getpid();
87 int r = snprintf(fifo_name1, sizeof(fifo_name1)-1,
88 "/tmp/bin1_%d_%.16lX.hex", pid, rand64[0]);
89 if (r < 0 || r >= (int)sizeof(fifo_name1))
90 {
91name_error:
92 error("failed to generate named pipe name: %s", strerror(errno));
93 }
94 r = snprintf(fifo_name2, sizeof(fifo_name2)-1, "/tmp/bin2_%d_%.16lX.hex",
95 pid, rand64[1]);
96 if (r < 0 || r >= (int)sizeof(fifo_name1))
97 goto name_error;
98 if (mkfifo(fifo_name1, S_IRUSR | S_IWUSR) != 0 ||
99 mkfifo(fifo_name2, S_IRUSR | S_IWUSR) != 0)
100 error("failed to create named pipe: %s", strerror(errno));
101
102 // Execute xxd #1
103 progs[pc] = "xxd";
104 pids[pc] = fork();
105 if (pids[pc] == 0)
106 {
107 if (dup2(fd1, STDIN_FILENO) < 0)
108 {
109dup2_error:
110 error("failed to dup file descriptor: %s", strerror(errno));
111 }
112 close(fd1);
113 fifo_name = fifo_name1;
114 fd = open(fifo_name, O_WRONLY);
115 if (fd < 0)
116 {
117open_error:
118 error("failed to open named pipe: %s", strerror(errno));
119 }
120 if (dup2(fd, STDOUT_FILENO) < 0)
121 goto dup2_error;
122 close(fd);
123 if (execlp(progs[pc], progs[pc], "-p", nullptr) != 0)
124 {
125execlp_error:

Callers 1

parseEmitFunction · 0.85

Calls 15

openFunction · 0.85
errorFunction · 0.85
strerrorFunction · 0.85
readFunction · 0.85
closeFunction · 0.85
getpidFunction · 0.85
snprintfFunction · 0.85
forkFunction · 0.85
dup2Function · 0.85
pipeFunction · 0.85
strcmpFunction · 0.85
waitpidFunction · 0.85

Tested by

no test coverage detected