Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* compilation: cc -lnewt -o build/ddstats ddstats.c */
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <poll.h>
- #include <newt.h>
- #define pabort(x) \
- do { \
- perror(x); \
- abort(); \
- } while (0);
- #define fabort(fmt, args...) \
- do { \
- fprintf(stderr, fmt "\n", ##args); \
- abort(); \
- } while (0);
- int main(int argc, char **argv)
- {
- pid_t child;
- int pipes[2];
- long unsigned filesize = 0;
- int i;
- for (i = 0; i < argc; i++)
- if (!strncmp("if=", argv[i], 3)) {
- struct stat st;
- char *eq = strchr(argv[i], '=');
- if (!eq)
- fabort("Can't find input file (if=*) on command line");
- eq++; /* forwards pointer to filename, after `=' */
- if (stat(eq, &st))
- pabort("stat");
- if (S_ISLNK(st.st_mode)) {
- int status;
- char *tmp = strdup(eq);
- eq = malloc(st.st_size);
- readlink(tmp, eq, st.st_size); /* follow syslink */
- free(tmp);
- status = stat(eq, &st);
- free(eq);
- if (status)
- pabort("stat");
- filesize = st.st_size;
- break; /* get out loop */
- } else if (S_ISREG(st.st_mode)) {
- filesize = st.st_size;
- break;
- } else
- fabort("%s is not a file or a symbolic link", eq);
- }
- assert(filesize > 0);
- if (pipe(pipes))
- pabort("pipe");
- child = fork();
- if (!child) { /* child process */
- dup2(pipes[1], STDERR_FILENO);
- argv[0] = "dd";
- execvp(argv[0], argv);
- } else if (child == -1) {
- pabort("fork");
- } else { /* parent process */
- newtComponent form;
- newtComponent cancel;
- newtComponent progress;
- char line[64];
- FILE *fp = fdopen(pipes[0], "r");
- struct pollfd pfd = {
- .fd = pipes[0],
- .events = POLLIN,
- };
- memset(line, '\0', sizeof(line));
- sleep(1); /* give dd time to install signal hanlder */
- newtInit();
- newtCls();
- newtCenteredWindow(64, 12, "DD PROGRESS");
- form = newtForm(NULL, NULL, 0);
- cancel = newtButton(28, 8, "cancel");
- progress = newtScale(4, 4, 56, filesize);
- newtFormAddComponent(form, progress);
- newtFormAddComponent(form, cancel);
- newtDrawForm(form);
- newtRefresh();
- while (!waitpid(child, NULL, WNOHANG)) { /* while child lives */
- kill(child, SIGUSR1); /* send signal to write stats on stderr */
- while (poll(&pfd, 1, 1000)) {
- int status;
- int bytes;
- fgets(line, 64, fp);
- if (!strstr(line, "bytes")) /* skip lines that doesn't match */
- continue;
- status = sscanf(line, "%d bytes", &bytes);
- if (status == 1)
- newtScaleSet(progress, bytes);
- newtRefresh();
- }
- }
- newtRunForm(form);
- newtFormDestroy(form);
- newtFinished();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement