void RetypeBagIfWritable(Obj obj, UInt new_type) { if (CheckWriteAccess(obj)) RetypeBag(obj, new_type); }
int UpdateDownload(CUCtrl p,int arc,char **arg) { LArray *remote; int i; int error=0; int count=0; if(CheckWriteAccess()!=0) { if(errno==ENOENT) status("yong.ini不存在"); else if(errno==EROFS) status("文件系统只读"); else status("没有更新文件的权限"); return -1; } status("下载远程文件列表"); remote=build_remote_file_list(); if(!remote) return -1; if(cu_quit_ui) { l_ptr_array_free(remote,(LFreeFunc)fitem_free); return -1; } for(i=0;i<remote->len && !cu_quit_ui;i++) { FITEM *it=l_ptr_array_nth(remote,i); char *md5; uint32_t size; if(!allow_update(it->file)) { continue; } md5=md5_file(it->file,&size); if(!md5) { continue; } if(size==it->size && !strcmp(md5,it->md5)) { l_free(md5); continue; } l_free(md5); if(cu_quit_ui) break; status("下载文件\"%s\"",it->file); if(download_remote_file(it)==-1) { error=1; break; } count++; } l_ptr_array_free(remote,(LFreeFunc)fitem_free); if(error==0) { if(count>0) status("更新完成"); else status("已经是最新的了"); } return 0; }
/* * read specified amount of bytes from given desc/offset to buffer * return amount of read bytes or negative error code if call failed */ int32_t ZVMReadHandle(struct NaClApp *nap, int ch, char *buffer, int32_t size, int64_t offset) { struct ChannelDesc *channel; int64_t tail; char *sys_buffer; int32_t retcode = ERR_CODE; assert(nap != NULL); assert(nap->system_manifest != NULL); assert(nap->system_manifest->channels != NULL); /* check the channel number */ if(ch < 0 || ch >= nap->system_manifest->channels_count) return -EINVAL; channel = &nap->system_manifest->channels[ch]; /* check buffer and convert address */ if(CheckWriteAccess(nap, buffer, size) == ERR_CODE) return -EINVAL; sys_buffer = (char*)NaClUserToSys(nap, (uintptr_t) buffer); /* prevent reading from the closed or not readable channel */ if(!CHANNEL_READABLE(channel)) return -EBADF; /* ignore user offset for sequential access read */ if(CHANNEL_SEQ_READABLE(channel)) offset = channel->getpos; else /* prevent reading beyond the end of the random access channels */ size = MIN(channel->size - offset, size); /* check arguments sanity */ if(size == 0) return 0; /* success. user has read 0 bytes */ if(size < 0) return -EFAULT; if(offset < 0) return -EINVAL; /* check for eof */ if(channel->eof) return 0; /* check limits */ if(channel->counters[GetsLimit] >= channel->limits[GetsLimit]) return -EDQUOT; if(CHANNEL_RND_READABLE(channel)) if(offset >= channel->limits[PutSizeLimit] - channel->counters[PutSizeLimit] + channel->size) return -EINVAL; /* calculate i/o leftovers */ tail = channel->limits[GetSizeLimit] - channel->counters[GetSizeLimit]; if(size > tail) size = tail; if(size < 1) return -EDQUOT; ZLOGS(LOG_DEBUG, "channel %s, buffer=0x%lx, size=%d, offset=%ld", channel->alias, (intptr_t)buffer, size, offset); /* read data and update position */ /* todo(d'b): when the reading operation hits channels end return EOF(-1?) */ switch(channel->source) { case ChannelRegular: retcode = pread(channel->handle, sys_buffer, (size_t)size, (off_t)offset); if(retcode == -1) retcode = -errno; break; case ChannelCharacter: case ChannelFIFO: case ChannelSocket: retcode = fread(sys_buffer, 1, (size_t)size, (FILE*)channel->socket); if(retcode == -1) retcode = -errno; break; case ChannelTCP: retcode = FetchMessage(channel, sys_buffer, size); if(retcode == -1) retcode = -EIO; break; default: /* design error */ ZLOGFAIL(1, EFAULT, "invalid channel source"); break; } /* update the channel counter, size, position and tag */ ++channel->counters[GetsLimit]; if(retcode > 0) { channel->counters[GetSizeLimit] += retcode; UpdateChannelTag(channel, (const char*)sys_buffer, retcode); /* * current get cursor. must be updated if channel have seq get * but there is nothing wrong to update it even it have random get */ channel->getpos = offset + retcode; /* if channel have random put update put cursor. not allowed for cdr */ if(CHANNEL_RND_WRITEABLE(channel)) channel->putpos = offset + retcode; } /* * set eof if 0 bytes has been read. it is safe because * 1. if user asked for a 0 bytes control will not reach this code * 2. if user asked more then 0 bytes and got 0 that means end of data * 3. if quota exceeded user will get an error before an actual read */ if(retcode == 0) channel->eof = 1; return retcode; }