int mingw_rmdir(const char *pathname) { int ret, tries = 0; while ((ret = rmdir(pathname)) == -1 && tries < ARRAY_SIZE(delay)) { if (!is_file_in_use_error(GetLastError())) break; if (!is_dir_empty(pathname)) { errno = ENOTEMPTY; break; } /* * We assume that some other process had the source or * destination file open at the wrong moment and retry. * In order to give the other process a higher chance to * complete its operation, we give up our time slice now. * If we have to retry again, we do sleep a bit. */ Sleep(delay[tries]); tries++; } while (ret == -1 && is_file_in_use_error(GetLastError()) && ask_yes_no_if_possible("Deletion of directory '%s' failed. " "Should I try again?", pathname)) ret = rmdir(pathname); return ret; }
bool is_dir_empty(FS* fs, uint32_t dir) { if (!fs) throw std::invalid_argument("iterate_dir invalid arg: fs"); open_inode inode(fs_open_inode(fs, dir)); return is_dir_empty(inode.get()); }
/* Mount FAT file system */ int mount_fat_filesystem(char *device) { int result; pid_t pid; if (!is_dir_empty(MOUNTPOINT)) { fprintf(stderr,"Mount point not empty\n"); return (-1); } char *arg[] = {MOUNT_FAT, "-t", "vfat", "-o", "umask=000", device, MOUNTPOINT, NULL}; pid = fork(); if (pid == -1) { perror(PNAME); exit(1); } if (pid == 0) { /* Tuxera NTFS-3g does not work for a setuid process unless ntfs3g-binary is suid root as well. This is discouraged, so we camouflage the fact that the program is running setuid */ setresuid(0,0,0); if (execv(MOUNT_FAT, arg) == -1) { fprintf(stderr, "this should not happen\n"); exit(1); } /* Not reached */ return (-1); } else { wait (&result); return (result); } /* Not reached */ return (-1); }
char *attach_file(char *prefix, char *command) { int i,result=42; char *path; pid_t pid; char *arg[10]; int ipipe[2]; char *loopback; struct stat statbuf; if (!is_dir_empty(MOUNTPOINT)) { fprintf(stderr,"Mount point not empty\n"); exit(1); } path = malloc(sizeof(char)*(strlen(prefix)+strlen(command)+1)); if (path == NULL) { perror(PNAME); exit(1); } strcpy(path, prefix); strcat(path, command); sanitize_path(path); if (lstat (path, &statbuf) == -1) { perror(PNAME); exit(1); } if (statbuf.st_nlink != 1) { fprintf(stderr, "File has hard links to it, cannot proceed.\n"); exit(1); } if ((statbuf.st_mode & S_IFMT) != S_IFREG) { fprintf(stderr, "file is not a regular file, go away\n"); exit(1); } /* A kludge to redirect child stdout back to parent to find a loopback device */ if (pipe(ipipe)) { perror(PNAME); exit(1); } /* Fork to run losetup -f to get a free loopback interface */ pid = fork(); if (pid == -1) { perror(PNAME); exit(1); } if (pid == 0) { close(STDOUT_FILENO); close(STDERR_FILENO); dup2(ipipe[1], STDOUT_FILENO); close(ipipe[0]); close(ipipe[1]); arg[0] = LOSETUP; arg[1] = "-f"; arg[2] = NULL; if (execv(LOSETUP, arg) == -1) { perror(PNAME); exit(1); } /* This is never reached */ return NULL; } else { close(ipipe[1]); loopback = malloc(256*sizeof(char)); if (loopback == NULL) { perror(PNAME); exit(1); } loopback[read(ipipe[0],loopback,256)] = 0; if (strlen(loopback) < 5) { fprintf(stderr, "no loopback device found\n"); wait(&result); close(ipipe[0]); exit(1); } /* Get a free loopback device to loopback */ loopback[strlen(loopback)-1] = 0; wait(&result); close(ipipe[0]); if (result != 0) { fprintf(stderr, "this should not happen, losetup -f did not return a proper value\n"); exit(result); } /* Attach the loopback device. Examine return value as not a single state operation */ arg[0] = LOSETUP; arg[1] = loopback; arg[2] = path; arg[3] = NULL; /* Fork to exec losetup /dev/loopx pathname */ pid = fork(); if (pid == -1) { perror(PNAME); exit(1); } if (pid == 0) { if (execv(LOSETUP, arg) == -1) { perror(PNAME); exit(1); } /* This is never reached */ return NULL; } else { wait (&result); if (result == 0) return loopback; else { free(loopback); return NULL; } } } }