static void setup_every_copy() { close(newdirfd); rmobj(TEST_DIR2, NULL); SUCCEED_OR_DIE(mkdir, "mkdir(%s, %o) failed: %s", TEST_DIR2, 0700); newdirfd = SUCCEED_OR_DIE(open, "open(%s, 0x%x) failed: %s", TEST_DIR2, O_DIRECTORY); }
int main() { struct databuf *buf1, *buf2; int semid = getsem(); getseg(&buf1, &buf2); reader(semid, buf1, buf2); writer(semid, buf1, buf2); rmobj(); }
OBJ *merge(OBJ * a, OBJ * b) { OBJ *obj = mkobj(); int an = 0, bn = 0; obj->ind = b->ind; while (an != a->n || bn != b->n) { if (an != a->n && bn != b->n) if (a->start[an] == b->start[bn]) { int x, z; obj->len[obj->n] = a->len[an] + b->len[bn] + 1; obj->siz[obj->n] = obj->len[obj->n] + 8; obj->glob[obj->n] = (int *) malloc(sizeof(int) * obj->siz[obj->n]); obj->start[obj->n] = a->start[an]; for (x = 0; x != a->len[an]; ++x) obj->glob[obj->n][x] = a->glob[an][x]; obj->glob[obj->n][x++] = ' '; for (z = 0; z != b->len[bn]; ++z) obj->glob[obj->n][x + z] = b->glob[bn][z]; obj->glob[obj->n][x + z] = 0; ++an; ++bn; } else if (a->start[an] < b->start[bn]) { /* Take a */ obj->glob[obj->n] = a->glob[an]; a->glob[an] = 0; obj->len[obj->n] = a->len[an]; obj->siz[obj->n] = a->siz[an]; obj->start[obj->n] = a->start[an]; ++an; } else { /* Take b */ obj->glob[obj->n] = b->glob[bn]; b->glob[bn] = 0; obj->len[obj->n] = b->len[bn]; obj->siz[obj->n] = b->siz[bn]; obj->start[obj->n] = b->start[bn]; ++bn; } else if (an != a->n) { /* Take a */ obj->glob[obj->n] = a->glob[an]; a->glob[an] = 0; obj->len[obj->n] = a->len[an]; obj->siz[obj->n] = a->siz[an]; obj->start[obj->n] = a->start[an]; ++an; } else { /* Take b */ obj->glob[obj->n] = b->glob[bn]; b->glob[bn] = 0; obj->len[obj->n] = b->len[bn]; obj->siz[obj->n] = b->siz[bn]; obj->start[obj->n] = b->start[bn]; ++bn; } ++obj->n; } rmobj(a); rmobj(b); return obj; }
int rmobj(char *obj, char **errmsg) { int ret_val = 0; /* return value from this routine */ DIR *dir; /* pointer to a directory */ struct dirent *dir_ent; /* pointer to directory entries */ char dirobj[PATH_MAX]; /* object inside directory to modify */ struct stat statbuf; /* used to hold stat information */ static char err_msg[1024]; /* error message */ /* Determine the file type */ if ( lstat(obj, &statbuf) < 0 ) { if ( errmsg != NULL ) { sprintf(err_msg, "lstat(%s) failed; errno=%d: %s", obj, errno, SYSERR); *errmsg = err_msg; } return -1; } /* Take appropriate action, depending on the file type */ if ( (statbuf.st_mode & S_IFMT) == S_IFDIR ) { /* object is a directory */ /* Do NOT perform the request if the directory is "/" */ if ( !strcmp(obj, "/") ) { if ( errmsg != NULL ) { sprintf(err_msg, "Cannot remove /"); *errmsg = err_msg; } return -1; } /* Open the directory to get access to what is in it */ if ( (dir = opendir(obj)) == NULL ) { if ( rmdir(obj) != 0 ) { if ( errmsg != NULL ) { sprintf(err_msg, "rmdir(%s) failed; errno=%d: %s", obj, errno, SYSERR); *errmsg = err_msg; } return -1; } else { return 0; } } /* Loop through the entries in the directory, removing each one */ for ( dir_ent = (struct dirent *)readdir(dir); dir_ent != NULL; dir_ent = (struct dirent *)readdir(dir)) { /* Don't remove "." or ".." */ if ( !strcmp(dir_ent->d_name, ".") || !strcmp(dir_ent->d_name, "..") ) continue; /* Recursively call this routine to remove the current entry */ sprintf(dirobj, "%s/%s", obj, dir_ent->d_name); if ( rmobj(dirobj, errmsg) != 0 ) ret_val = -1; } /* Close the directory */ closedir(dir); /* If there were problems removing an entry, don't attempt to remove the directory itself */ if ( ret_val == -1 ) return -1; /* Get the link count, now that all the entries have been removed */ if ( lstat(obj, &statbuf) < 0 ) { if ( errmsg != NULL ) { sprintf(err_msg, "lstat(%s) failed; errno=%d: %s", obj, errno, SYSERR); *errmsg = err_msg; } return -1; } /* Remove the directory itself */ if ( statbuf.st_nlink >= 3 ) { /* The directory is linked; unlink() must be used */ if ( unlink(obj) < 0 ) { if ( errmsg != NULL ) { sprintf(err_msg, "unlink(%s) failed; errno=%d: %s", obj, errno, SYSERR); *errmsg = err_msg; } return -1; } } else { /* The directory is not linked; rmdir() can be used */ if ( rmdir(obj) < 0 ) { if ( errmsg != NULL ) { sprintf(err_msg, "remove(%s) failed; errno=%d: %s", obj, errno, SYSERR); *errmsg = err_msg; } return -1; } } } else { /* object is not a directory; just use unlink() */ if ( unlink(obj) < 0 ) { if ( errmsg != NULL ) { sprintf(err_msg, "unlink(%s) failed; errno=%d: %s", obj, errno, SYSERR); *errmsg = err_msg; } return -1; } } /* if obj is a directory */ /* * Everything must have went ok. */ return 0; } /* rmobj() */