/* * util_unlink_flock -- flocks the file and unlinks it * * The unlink(2) call on a file which is opened and locked using flock(2) * by different process works on linux. Thus in order to forbid removing a * pool when in use by different process we need to flock(2) the pool files * first before unlinking. */ int util_unlink_flock(const char *path) { LOG(3, "path \"%s\"", path); #ifdef WIN32 /* * On Windows it is not possible to unlink the * file if it is flocked. */ return util_unlink(path); #else int fd = util_file_open(path, NULL, 0, O_RDONLY); if (fd < 0) { LOG(2, "failed to open file \"%s\"", path); return -1; } int ret = util_unlink(path); (void) os_close(fd); return ret; #endif }
static int read_write ( const char *basepath, UMSDOS_REGISTER ®, int line_length) { /* #Specification: utstspc / read write We write files with special pattern and read it back using different blocking scheme. This is to make sure the new read ahead support in the msdos fs is not screwing. */ char fname[MAXSIZ_PATH]; sprintf (fname,"%s/file.c",basepath); int size = read_initfile(fname,reg,line_length); if (size != -1){ reg.verbose ("Creating a %d bytes file %s (line length %d)\n" ,size,fname,line_length); static int tb[]={ 4096,2048,1024,512,513,255,50,256*1024 }; for (unsigned int i=0; i<sizeof(tb)/sizeof(tb[0]) && reg.getnberr()==0; i++){ reg.verbose ("\tTesting block size %d\n",tb[i]); read_checkfile (fname,reg,tb[i],size,line_length); } util_unlink (fname,reg,0); } return reg.getnberr(); }
static int mmap_simple (const char *path) { char fname[MAXSIZ_PATH]; sprintf (fname,"%s/file",path); FILE *f = util_fopen(fname,"w",Rmmap_simple); if (f != NULL){ short int buf[10000]; int i; for (i=0; (unsigned int) i<sizeof(buf)/sizeof(buf[0]); i++)buf[i] = i; if (fwrite (buf,1,sizeof(buf),f)!=sizeof(buf)){ Rmmap_simple.prterr ("Can't write %d bytes\n",sizeof(buf)); }else{ fclose (f); Rmmap_simple.verbose ("%d bytes were written to %s\n" ,sizeof(buf),fname); f = util_fopen(fname,"r",Rmmap_simple); int mmap_size = sizeof(buf) * 2; short int *ptm = (short int*)mmap(0,mmap_size ,PROT_READ,MAP_SHARED,fileno(f),0); if (ptm == (short int*)-1){ Rmmap_simple.prterr ("Can't mmap: errno = %d %s\n" ,errno,strerror(errno)); }else{ /* This test try to prove that mmaping beyong eof yields all 0s. It does not work, so I changed the target of the loop so it test only below eof. */ Rmmap_simple.verbose ("mmap returned %p\n",ptm); int nbelm_buf = sizeof(buf)/sizeof(buf[0]); //for (i=0; i<mmap_size/sizeof(buf[0]); i++){ for (i=0; i<nbelm_buf; i++){ Rmmap_simple.verbose ("%d ",i); fflush(stdout); if (i > nbelm_buf){ if (ptm[i] != 0){ Rmmap_simple.prterr("Error reading beyond eof at offset %d\n" ,i*sizeof(buf[0])); break; } }else if (ptm[i] != i){ Rmmap_simple.prterr("Error reading at offset %d\n" ,i*sizeof(buf[0])); break; } } if (munmap((char*)ptm,sizeof(buf))==-1){ Rmmap_simple.prterr ("Can't munmap\n"); } } } fclose (f); util_unlink(fname,Rmmap_simple,0); } return Rmmap_simple.getnberr(); }
/* Test many hlinkink chain to point to a file fpath */ static void hlink_many ( const char *fpath, // target of the link const char *lpath, // base name for hard link int fpath_exist, // fpath does exist or not UMSDOS_REGISTER ®) { if (reg.getnberr()==0){ /* #Specification: utstspc / hard links / case / link 2 link 2 link ... hlink_simple does test a link made to a link made to a link and so on. On a normal UNIX file system, this test is not really an issue. Given the fact that a hardlink on UMSDOS is a symlink to a hidden file, it make sense to test at least the two cases: hard link to an existing file with no link hard link to an existing file with more than one link. */ int i; for (i=0; i<6 && reg.getnberr()==0; i++){ char spath1[MAXSIZ_PATH]; if (i > 0){ strcpy (spath1,lpath); for (int j=0; j<i; j++) strcat (spath1,".s"); }else{ strcpy (spath1,fpath); } char spath2[MAXSIZ_PATH]; strcpy (spath2,lpath); for (int j=0; j<=i; j++) strcat (spath2,".s"); if (fpath_exist){ util_hardlink (spath1,spath2,reg,0); struct stat info; if (util_stat (spath2,&info,reg,0)!=-1 && info.st_size != 6){ reg.prterr ( "Invalid dimension for %s\n",spath2); } hlink_checkhello (spath2,reg); }else{ util_hardlink (spath1,spath2,reg,ENOENT); } } if (fpath_exist){ // Cleanup char spath[MAXSIZ_PATH]; strcpy (spath,lpath); for (i=0; i<=5; i++){ strcat (spath,".s"); util_unlink (spath,reg,0); } } } }
static int dir_simple(const char *basepath) { char path[MAXSIZ_PATH]; sprintf (path,"%s/dir",basepath); Rdir_simple.verbose ("Creating directory %s\n",path); if (util_mkdir(path,0777,Rdir_simple,0)!=-1){ if (util_dir_count (path,Rdir_simple)!=2){ Rdir_simple.prterr ("Empty directory not empty ??\n"); } util_mkdir (path,0777,Rdir_simple,EEXIST); util_create (path,0666,Rdir_simple,EISDIR); char fpath[MAXSIZ_PATH]; sprintf (fpath,"%s/file1",path); util_create (fpath,0666,Rdir_simple,0); util_mkdir (fpath,0777,Rdir_simple,EEXIST); util_rmdir (path,Rdir_simple,ENOTEMPTY); util_rmdir (fpath,Rdir_simple,ENOTDIR); util_unlink (fpath,Rdir_simple,0); util_mkdir (path,0777,Rdir_simple,EEXIST); util_unlink (path,Rdir_simple,EISDIR); util_rmdir (path,Rdir_simple,0); } return Rdir_simple.getnberr(); }
static int hlink_simple (const char *basepath) { char dpath[MAXSIZ_PATH]; sprintf (dpath,"%s/dir",basepath); if (util_mkdir (dpath,0777,Rhlink_simple,0)!=-1){ char fpath[MAXSIZ_PATH]; sprintf (fpath,"%s/file",dpath); FILE *fout = util_fopen (fpath,"w",Rhlink_simple); if (fout != NULL){ fprintf (fout,"hello\n"); fclose (fout); hlink_many (fpath,fpath,1,Rhlink_simple); /* #Specification: utstgen / hard link / cases / across directory boundary The target of the link is not in the same directory as the new link. */ char ddpath[MAXSIZ_PATH]; sprintf (ddpath,"%s/sdir",dpath); if (util_mkdir (ddpath,0777,Rhlink_simple,0)!=-1){ char spath[MAXSIZ_PATH]; sprintf (spath,"%s/file",ddpath); hlink_many (fpath,spath,0,Rhlink_simple); util_rmdir (ddpath,Rhlink_simple,0); } util_unlink (fpath,Rhlink_simple,0); /* #Specification: utstgen / hard link / cases / target does not exist Many hard links are attempted to a file which does not exist. */ hlink_many (fpath,fpath,0,Rhlink_simple); } /* #Specification: utstgen / hard link / to a directory A hard link can't be made to a directory. */ char spath[MAXSIZ_PATH]; sprintf (spath,"%s/error",basepath); util_hardlink (dpath,spath,Rhlink_simple,EPERM); util_rmdir (dpath,Rhlink_simple,0); } return Rhlink_simple.getnberr(); }
/* * replica_remove_part -- unlink part from replica */ int replica_remove_part(struct pool_set *set, unsigned repn, unsigned partn) { LOG(3, "set %p, repn %u, partn %u", set, repn, partn); struct pool_set_part *part = &PART(REP(set, repn), partn); if (part->fd != -1) { close(part->fd); part->fd = -1; } int olderrno = errno; if (util_unlink(part->path)) { if (errno != ENOENT) { ERR("removing part %u from replica %u failed", partn, repn); return -1; } } errno = olderrno; LOG(1, "Removed part %s number %u from replica %u", part->path, partn, repn); return 0; }
/* * rm_file -- remove single file */ static void rm_file(const char *file) { int write_protected = access(file, W_OK) != 0; char cask = 'y'; switch (ask_mode) { case ASK_ALWAYS: cask = '?'; break; case ASK_NEVER: cask = 'y'; break; case ASK_SOMETIMES: cask = write_protected ? '?' : 'y'; break; } const char *pre_msg = write_protected ? "write-protected " : ""; if (ask_Yn(cask, "remove %sfile '%s' ?", pre_msg, file) == 'y') { if (util_unlink(file)) err(1, "cannot remove file '%s'", file); outv(1, "removed '%s'\n", file); } }
static int hlink_simple (const char *basepath) { /* #Specification: utstspc / hard link / subdirectory of a dos directory We create two subdirectory in a DOS directory. We switch those to Umsdos mode (umssync). We set a lot of hard link between those two directories. This test try to demonstrate that the only thing that matter is that both subdirectory must be umsdos directories. But the parents don't have to. */ char dpath1[MAXSIZ_PATH]; sprintf (dpath1,"%s/dir1",basepath); if (utilspc_mkdir_udos (dpath1,0777,Rhlink_simple)!=-1){ char fpath[MAXSIZ_PATH]; sprintf (fpath,"%s/file",dpath1); FILE *fout = util_fopen (fpath,"w",Rhlink_simple); if (fout != NULL){ fprintf (fout,"hello\n"); fclose (fout); hlink_many (fpath,fpath,1,Rhlink_simple); /* #Specification: utstspc / hard link / cases / across directory boundary The target of the link is not in the same directory as the new link. */ char dpath2[MAXSIZ_PATH]; sprintf (dpath2,"%s/dir2",basepath); if (utilspc_mkdir_udos (dpath2,0777,Rhlink_simple)!=-1){ char spath[MAXSIZ_PATH]; sprintf (spath,"%s/file",dpath2); hlink_many (fpath,spath,1,Rhlink_simple); util_rmdir (dpath2,Rhlink_simple,0); } char dpath3[MAXSIZ_PATH]; sprintf (dpath3,"%s/dir3",basepath); if (util_mkdir (dpath3,0777,Rhlink_simple,0)!=-1){ /* #Specification: utstspc / hard link / in a DOS directory A test is done to demonstrate that a hard link can't be created in a DOS directory. */ char spath[MAXSIZ_PATH]; sprintf (spath,"%s/file",dpath3); util_hardlink (fpath,spath,Rhlink_simple,EINVAL); util_rmdir (dpath3,Rhlink_simple,0); } util_unlink (fpath,Rhlink_simple,0); /* #Specification: utstspc / hard link / cases / target does not exist Many hard links are attempted to a file which does not exist. */ hlink_many (fpath,fpath,0,Rhlink_simple); } /* #Specification: utstspc / hard link / to a directory A hard link can't be made to a directory. */ char spath[MAXSIZ_PATH]; sprintf (spath,"%s/error",basepath); util_hardlink (dpath1,spath,Rhlink_simple,EPERM); util_rmdir (dpath1,Rhlink_simple,0); } return Rhlink_simple.getnberr(); }