static int file_stats(int pdev,int pino,PVStr(path),PCStr(file),FileStat *stp,int *blocksp) { int rcode,blocks; if( FS_withSymlink() ){ if( F_FOLLOW_SYMLINK ) rcode = stat(file,stp); else rcode = lstat(file,stp); }else{ rcode = stat(file,stp); } if( rcode == 0 ){ blocks = stat_blocks(stp); if( blocksp ) *blocksp = blocks; put_inocache(pdev,pino,AVStr(path),stp,blocks); return S_ISDIR(stp->st_mode); }else return -1; }
/* <string> status false */ static int zstatus(i_ctx_t *i_ctx_p) { os_ptr op = osp; switch (r_type(op)) { case t_file: { stream *s; make_bool(op, (file_is_valid(s, op) ? 1 : 0)); } return 0; case t_string: { gs_parsed_file_name_t pname; struct stat fstat; int code = parse_file_name(op, &pname, i_ctx_p->LockFilePermissions); if (code < 0) return code; code = gs_terminate_file_name(&pname, imemory, "status"); if (code < 0) return code; code = (*pname.iodev->procs.file_status)(pname.iodev, pname.fname, &fstat); switch (code) { case 0: check_ostack(4); /* * Check to make sure that the file size fits into * a PostScript integer. (On some systems, long is * 32 bits, but file sizes are 64 bits.) */ push(4); make_int(op - 4, stat_blocks(&fstat)); make_int(op - 3, fstat.st_size); /* * We can't check the value simply by using ==, * because signed/unsigned == does the wrong thing. * Instead, since integer assignment only keeps the * bottom bits, we convert the values to double * and then test for equality. This handles all * cases of signed/unsigned or width mismatch. */ if ((double)op[-4].value.intval != (double)stat_blocks(&fstat) || (double)op[-3].value.intval != (double)fstat.st_size ) return_error(e_limitcheck); make_int(op - 2, fstat.st_mtime); make_int(op - 1, fstat.st_ctime); make_bool(op, 1); break; case e_undefinedfilename: make_bool(op, 0); code = 0; } gs_free_file_name(&pname, "status"); return code; } default: return_op_typecheck(op); } }