diff options
author | Haru <haru@dotalux.com> | 2015-01-24 03:42:16 +0100 |
---|---|---|
committer | Haru <haru@dotalux.com> | 2015-01-24 03:42:36 +0100 |
commit | a75714ca455c728d34918dd12200fcec87ebc0d4 (patch) | |
tree | d95d174b239a14fafdb8e824bad4a9c81a5a5a80 | |
parent | df8d6560fc7eb34806d27d28b8b7dbce36868c24 (diff) | |
download | hercules-a75714ca455c728d34918dd12200fcec87ebc0d4.tar.gz hercules-a75714ca455c728d34918dd12200fcec87ebc0d4.tar.bz2 hercules-a75714ca455c728d34918dd12200fcec87ebc0d4.tar.xz hercules-a75714ca455c728d34918dd12200fcec87ebc0d4.zip |
Fixed 18 minor issues
Signed-off-by: Haru <haru@dotalux.com>
-rw-r--r-- | src/char/geoip.c | 7 | ||||
-rw-r--r-- | src/char/int_auction.c | 2 | ||||
-rw-r--r-- | src/char/inter.c | 2 | ||||
-rw-r--r-- | src/common/ers.c | 3 | ||||
-rw-r--r-- | src/common/grfio.c | 151 | ||||
-rw-r--r-- | src/common/md5calc.c | 4 | ||||
-rw-r--r-- | src/common/socket.c | 29 | ||||
-rw-r--r-- | src/common/sql.c | 10 | ||||
-rw-r--r-- | src/common/utils.c | 57 |
9 files changed, 169 insertions, 96 deletions
diff --git a/src/char/geoip.c b/src/char/geoip.c index 1268019e1..889958e16 100644 --- a/src/char/geoip.c +++ b/src/char/geoip.c @@ -136,7 +136,7 @@ void geoip_init(void) geoip->final(false); return; } - geoip->data->cache = aMalloc( (sizeof(geoip->data->cache) * bufa.st_size) ); + geoip->data->cache = aMalloc(sizeof(unsigned char) * bufa.st_size); if (fread(geoip->data->cache, sizeof(unsigned char), bufa.st_size, db) != bufa.st_size) { ShowError("geoip_cache: Couldn't read all elements!\n"); fclose(db); @@ -157,7 +157,10 @@ void geoip_init(void) } break; } else { - fseek(db, -4l, SEEK_CUR); + if (fseek(db, -4l, SEEK_CUR) != 0) { + db_type = 0; + break; + } } } diff --git a/src/char/int_auction.c b/src/char/int_auction.c index 164ca5360..57eae641d 100644 --- a/src/char/int_auction.c +++ b/src/char/int_auction.c @@ -105,7 +105,7 @@ unsigned int inter_auction_create(struct auction_data *auction) else { struct auction_data *auction_; - int64 tick = auction->hours * 3600000; + int64 tick = (int64)auction->hours * 3600000; auction->item.amount = 1; auction->item.identify = 1; diff --git a/src/char/inter.c b/src/char/inter.c index 5af9a6aab..eb14f1593 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -690,9 +690,11 @@ int inter_accreg_fromsql(int account_id,int char_id, int fd, int type) if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", acc_reg_num_db, account_id) ) Sql_ShowDebug(inter->sql_handle); break; +#if 0 // This is already checked above. case 1: //account2 reg ShowError("inter->accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); return 0; +#endif // 0 } WFIFOHEAD(fd, 60000 + 300); diff --git a/src/common/ers.c b/src/common/ers.c index 489d8f7ae..52cba0fe5 100644 --- a/src/common/ers.c +++ b/src/common/ers.c @@ -308,8 +308,11 @@ ERS *ers_new(uint32 size, char *name, enum ERSOptions options) CREATE(instance,struct ers_instance_t, 1); size += sizeof(struct ers_list); + +#if ERS_ALIGNED > 1 // If it's aligned to 1-byte boundaries, no need to bother. if (size % ERS_ALIGNED) size += ERS_ALIGNED - size % ERS_ALIGNED; +#endif instance->VTable.alloc = ers_obj_alloc_entry; instance->VTable.free = ers_obj_free_entry; diff --git a/src/common/grfio.c b/src/common/grfio.c index 28e6c87f4..d226fb158 100644 --- a/src/common/grfio.c +++ b/src/common/grfio.c @@ -402,51 +402,72 @@ static void grfio_localpath_create(char* buffer, size_t size, const char* filena /// Reads a file into a newly allocated buffer (from grf or data directory). -void* grfio_reads(const char* fname, int* size) +void *grfio_reads(const char *fname, int *size) { - unsigned char* buf2 = NULL; - FILELIST* entry = filelist_find(fname); - if( entry == NULL || entry->gentry <= 0 ) {// LocalFileCheck + if (entry == NULL || entry->gentry <= 0) { + // LocalFileCheck char lfname[256]; - FILE* in; - grfio_localpath_create(lfname, sizeof(lfname), ( entry && entry->fnd ) ? entry->fnd : fname); + FILE *in; + unsigned char *buf = NULL; + grfio_localpath_create(lfname, sizeof(lfname), (entry && entry->fnd) ? entry->fnd : fname); in = fopen(lfname, "rb"); - if( in != NULL ) { + if (in != NULL) { int declen; fseek(in,0,SEEK_END); declen = (int)ftell(in); + if (declen == -1) { + ShowError("An error occurred in fread grfio_reads, fname=%s \n",fname); + fclose(in); + return NULL; + } fseek(in,0,SEEK_SET); - buf2 = (unsigned char *)aMalloc(declen+1); // +1 for resnametable zero-termination - if(fread(buf2, 1, declen, in) != (size_t)declen) ShowError("An error occurred in fread grfio_reads, fname=%s \n",fname); + buf = (unsigned char *)aMalloc(declen+1); // +1 for resnametable zero-termination + buf[declen] = '\0'; + if (fread(buf, 1, declen, in) != (size_t)declen) { + ShowError("An error occurred in fread grfio_reads, fname=%s \n",fname); + aFree(buf); + fclose(in); + return NULL; + } fclose(in); - if( size ) + if (size) *size = declen; - } else { - if (entry != NULL && entry->gentry < 0) { - entry->gentry = -entry->gentry; // local file checked - } else { - ShowError("grfio_reads: %s not found (local file: %s)\n", fname, lfname); - return NULL; - } + return buf; } + + if (entry == NULL || entry->gentry >= 0) { + ShowError("grfio_reads: %s not found (local file: %s)\n", fname, lfname); + return NULL; + } + + entry->gentry = -entry->gentry; // local file checked } - if( entry != NULL && entry->gentry > 0 ) {// Archive[GRF] File Read - char* grfname = gentry_table[entry->gentry - 1]; - FILE* in = fopen(grfname, "rb"); - if( in != NULL ) { + if (entry != NULL && entry->gentry > 0) { + // Archive[GRF] File Read + char *grfname = gentry_table[entry->gentry - 1]; + FILE *in = fopen(grfname, "rb"); + + if (in != NULL) { int fsize = entry->srclen_aligned; unsigned char *buf = (unsigned char *)aMalloc(fsize); - fseek(in, entry->srcpos, 0); - if(fread(buf, 1, fsize, in) != (size_t)fsize) ShowError("An error occurred in fread in grfio_reads, grfname=%s\n",grfname); + unsigned char *buf2 = NULL; + if (fseek(in, entry->srcpos, SEEK_SET) != 0 + || fread(buf, 1, fsize, in) != (size_t)fsize) { + ShowError("An error occurred in fread in grfio_reads, grfname=%s\n",grfname); + aFree(buf); + fclose(in); + return NULL; + } fclose(in); buf2 = (unsigned char *)aMalloc(entry->declen+1); // +1 for resnametable zero-termination - if( entry->type & FILELIST_TYPE_FILE ) - {// file + buf2[entry->declen] = '\0'; + if (entry->type & FILELIST_TYPE_FILE) { + // file uLongf len; grf_decode(buf, fsize, entry->type, entry->srclen); len = entry->declen; @@ -457,21 +478,23 @@ void* grfio_reads(const char* fname, int* size) aFree(buf2); return NULL; } - } else {// directory? + } else { + // directory? memcpy(buf2, buf, entry->declen); } - if( size ) + if (size) *size = entry->declen; aFree(buf); + return buf2; } else { ShowError("grfio_reads: %s not found (GRF file: %s)\n", fname, grfname); return NULL; } } - return buf2; + return NULL; } @@ -506,26 +529,31 @@ static bool isFullEncrypt(const char* fname) /// Loads all entries in the specified grf file into the filelist. /// @param gentry index of the grf file name in the gentry_table -static int grfio_entryread(const char* grfname, int gentry) +static int grfio_entryread(const char *grfname, int gentry) { long grf_size; unsigned char grf_header[0x2e] = { 0 }; int entry,entrys,ofs,grf_version; unsigned char *grf_filelist; - FILE* fp = fopen(grfname, "rb"); + FILE *fp = fopen(grfname, "rb"); if( fp == NULL ) { ShowWarning("GRF data file not found: '%s'\n",grfname); return 1; // 1:not found error - } else + } else { ShowInfo("GRF data file found: '%s'\n",grfname); + } fseek(fp,0,SEEK_END); grf_size = ftell(fp); fseek(fp,0,SEEK_SET); - if(fread(grf_header,1,0x2e,fp) != 0x2e) { ShowError("Couldn't read all grf_header element of %s \n", grfname); } - if( strcmp((const char*)grf_header,"Master of Magic") != 0 || fseek(fp,getlong(grf_header+0x1e),SEEK_CUR) != 0 ) { + if (fread(grf_header,1,0x2e,fp) != 0x2e) { + ShowError("Couldn't read all grf_header element of %s \n", grfname); + fclose(fp); + return 2; // 2:file format error + } + if (strcmp((const char*)grf_header,"Master of Magic") != 0 || fseek(fp,getlong(grf_header+0x1e),SEEK_CUR) != 0) { fclose(fp); ShowError("GRF %s read error\n", grfname); return 2; // 2:file format error @@ -533,32 +561,37 @@ static int grfio_entryread(const char* grfname, int gentry) grf_version = getlong(grf_header+0x2a) >> 8; - if( grf_version == 0x01 ) {// ****** Grf version 01xx ****** + if (grf_version == 0x01) { + // ****** Grf version 01xx ****** long list_size; list_size = grf_size - ftell(fp); - grf_filelist = (unsigned char *) aMalloc(list_size); - if(fread(grf_filelist,1,list_size,fp) != (size_t)list_size) { ShowError("Couldn't read all grf_filelist element of %s \n", grfname); } + grf_filelist = (unsigned char *)aMalloc(list_size); + if (fread(grf_filelist,1,list_size,fp) != (size_t)list_size) { + ShowError("Couldn't read all grf_filelist element of %s \n", grfname); + aFree(grf_filelist); + fclose(fp); + return 2; // 2:file format error + } fclose(fp); entrys = getlong(grf_header+0x26) - getlong(grf_header+0x22) - 7; // Get an entry - for( entry = 0, ofs = 0; entry < entrys; ++entry ) { + for (entry = 0, ofs = 0; entry < entrys; ++entry) { FILELIST aentry; - int ofs2 = ofs+getlong(grf_filelist+ofs)+4; unsigned char type = grf_filelist[ofs2+12]; - if( type & FILELIST_TYPE_FILE ) { - char* fname = decode_filename(grf_filelist+ofs+6, grf_filelist[ofs]-6); + if (type&FILELIST_TYPE_FILE) { + char *fname = decode_filename(grf_filelist+ofs+6, grf_filelist[ofs]-6); int srclen = getlong(grf_filelist+ofs2+0) - getlong(grf_filelist+ofs2+8) - 715; - if( strlen(fname) > sizeof(aentry.fn) - 1 ) { + if (strlen(fname) > sizeof(aentry.fn) - 1) { ShowFatalError("GRF file name %s is too long\n", fname); aFree(grf_filelist); - exit(EXIT_FAILURE); + return 5; // 5: file name too long } - type |= ( isFullEncrypt(fname) ) ? FILELIST_TYPE_ENCRYPT_MIXED : FILELIST_TYPE_ENCRYPT_HEADER; + type |= isFullEncrypt(fname) ? FILELIST_TYPE_ENCRYPT_MIXED : FILELIST_TYPE_ENCRYPT_HEADER; aentry.srclen = srclen; aentry.srclen_aligned = getlong(grf_filelist+ofs2+4)-37579; @@ -579,45 +612,55 @@ static int grfio_entryread(const char* grfname, int gentry) } aFree(grf_filelist); - } else if( grf_version == 0x02 ) {// ****** Grf version 02xx ****** + } else if (grf_version == 0x02) { + // ****** Grf version 02xx ****** unsigned char eheader[8]; unsigned char *rBuf; uLongf rSize, eSize; - if(fread(eheader,1,8,fp) != 8) ShowError("An error occurred in fread while reading header buffer\n"); + if (fread(eheader,1,8,fp) != 8) { + ShowError("An error occurred in fread while reading header buffer\n"); + fclose(fp); + return 4; + } rSize = getlong(eheader); // Read Size eSize = getlong(eheader+4); // Extend Size - if( (long)rSize > grf_size-ftell(fp) ) { + if ((long)rSize > grf_size-ftell(fp)) { fclose(fp); ShowError("Illegal data format: GRF compress entry size\n"); return 4; } rBuf = (unsigned char *)aMalloc(rSize); // Get a Read Size - grf_filelist = (unsigned char *)aMalloc(eSize); // Get a Extend Size - if(fread(rBuf,1,rSize,fp) != rSize) ShowError("An error occurred in fread \n"); + if (fread(rBuf,1,rSize,fp) != rSize) { + ShowError("An error occurred in fread \n"); + fclose(fp); + aFree(rBuf); + return 4; + } fclose(fp); + grf_filelist = (unsigned char *)aMalloc(eSize); // Get a Extend Size decode_zip(grf_filelist, &eSize, rBuf, rSize); // Decode function aFree(rBuf); entrys = getlong(grf_header+0x26) - 7; // Get an entry - for( entry = 0, ofs = 0; entry < entrys; ++entry ) { + for (entry = 0, ofs = 0; entry < entrys; ++entry) { FILELIST aentry; - - char* fname = (char*)(grf_filelist+ofs); + char *fname = (char*)(grf_filelist+ofs); int ofs2 = ofs + (int)strlen(fname)+1; int type = grf_filelist[ofs2+12]; - if( strlen(fname) > sizeof(aentry.fn)-1 ) { + if (strlen(fname) > sizeof(aentry.fn)-1) { ShowFatalError("GRF file name %s is too long\n", fname); aFree(grf_filelist); - exit(EXIT_FAILURE); + return 5; // 5: file name too long } - if( type & FILELIST_TYPE_FILE ) {// file + if (type&FILELIST_TYPE_FILE) { + // file aentry.srclen = getlong(grf_filelist+ofs2+0); aentry.srclen_aligned = getlong(grf_filelist+ofs2+4); aentry.declen = getlong(grf_filelist+ofs2+8); diff --git a/src/common/md5calc.c b/src/common/md5calc.c index 18e502da2..7b31a38d6 100644 --- a/src/common/md5calc.c +++ b/src/common/md5calc.c @@ -222,12 +222,12 @@ void MD5_Binary(const char * string, unsigned char * output) } /** output is the coded character sequence in the character sequence which wants to code string. */ -void MD5_String(const char * string, char * output) +void MD5_String(const char *string, char *output) { unsigned char digest[16]; MD5_String2binary(string,digest); - sprintf(output, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + snprintf(output, 33, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", digest[ 0], digest[ 1], digest[ 2], digest[ 3], digest[ 4], digest[ 5], digest[ 6], digest[ 7], digest[ 8], digest[ 9], digest[10], digest[11], diff --git a/src/common/socket.c b/src/common/socket.c index 9fe08e6f1..1b7f36f8b 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -311,15 +311,18 @@ void setsocketopts(int fd, struct hSockOpt *opt) { // set SO_REAUSEADDR to true, unix only. on windows this option causes // the previous owner of the socket to give up, which is not desirable // in most cases, neither compatible with unix. - sSetsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof(yes)); + if (sSetsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof(yes))) + ShowWarning("setsocketopts: Unable to set SO_REUSEADDR mode for connection #%d!\n", fd); #ifdef SO_REUSEPORT - sSetsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof(yes)); -#endif -#endif + if (sSetsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof(yes))) + ShowWarning("setsocketopts: Unable to set SO_REUSEPORT mode for connection #%d!\n", fd); +#endif // SO_REUSEPORT +#endif // WIN32 // Set the socket into no-delay mode; otherwise packets get delayed for up to 200ms, likely creating server-side lag. // The RO protocol is mainly single-packet request/response, plus the FIFO model already does packet grouping anyway. - sSetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes)); + if (sSetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes))) + ShowWarning("setsocketopts: Unable to set TCP_NODELAY mode for connection #%d!\n", fd); if( opt && opt->setTimeo ) { struct timeval timeout; @@ -327,8 +330,10 @@ void setsocketopts(int fd, struct hSockOpt *opt) { timeout.tv_sec = 5; timeout.tv_usec = 0; - sSetsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)); - sSetsockopt(fd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout)); + if (sSetsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout))) + ShowWarning("setsocketopts: Unable to set SO_RCVTIMEO for connection #%d!\n", fd); + if (sSetsockopt(fd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout))) + ShowWarning("setsocketopts: Unable to set SO_SNDTIMEO for connection #%d!\n", fd); } // force the socket into no-wait, graceful-close mode (should be the default, but better make sure) @@ -339,10 +344,12 @@ void setsocketopts(int fd, struct hSockOpt *opt) { ShowWarning("setsocketopts: Unable to set SO_LINGER mode for connection #%d!\n", fd); #ifdef TCP_THIN_LINEAR_TIMEOUTS - setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, &yes, sizeof yes); + if (sSetsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, (char *)&yes, sizeof(yes))) + ShowWarning("setsocketopts: Unable to set TCP_THIN_LINEAR_TIMEOUTS mode for connection #%d!\n", fd); #endif #ifdef TCP_THIN_DUPACK - setsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, &yes, sizeof yes); + if (sSetsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, (char *)&yes, sizeof(yes))) + ShowWarning("setsocketopts: Unable to set TCP_THIN_DUPACK mode for connection #%d!\n", fd); #endif } @@ -1276,6 +1283,10 @@ int socket_getips(uint32* ips, int max) u_long ad; fd = sSocket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) { + ShowError("socket_getips: Unable to create a socket!\n"); + return 0; + } memset(buf, 0x00, sizeof(buf)); diff --git a/src/common/sql.c b/src/common/sql.c index aec2ae93d..4ca14d43b 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -1027,9 +1027,8 @@ void Sql_HerculesUpdateCheck(Sql* self) { continue; } - fseek (ufp,1,SEEK_SET);/* woo. skip the # */ - - if( fgets(timestamp,sizeof(timestamp),ufp) ) { + if (fseek(ufp,1,SEEK_SET) == 0 /* woo. skip the # */ + && fgets(timestamp,sizeof(timestamp),ufp)) { unsigned int timestampui = (unsigned int)atol(timestamp); if( SQL_ERROR == SQL->Query(self, "SELECT 1 FROM `sql_updates` WHERE `timestamp` = '%u' LIMIT 1", timestampui) ) Sql_ShowDebug(self); @@ -1070,9 +1069,8 @@ void Sql_HerculesUpdateSkip(Sql* self,const char *filename) { return; } - fseek (ifp,1,SEEK_SET);/* woo. skip the # */ - - if( fgets(timestamp,sizeof(timestamp),ifp) ) { + if (fseek (ifp,1,SEEK_SET) == 0 /* woo. skip the # */ + && fgets(timestamp,sizeof(timestamp),ifp)) { unsigned int timestampui = (unsigned int)atol(timestamp); if( SQL_ERROR == SQL->Query(self, "SELECT 1 FROM `sql_updates` WHERE `timestamp` = '%u' LIMIT 1", timestampui) ) Sql_ShowDebug(self); diff --git a/src/common/utils.c b/src/common/utils.c index c168bd74e..ad68706ca 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -354,40 +354,51 @@ const char* timestamp2string(char* str, size_t size, time_t timestamp, const cha /* [Ind/Hercules] Caching */ -bool HCache_check(const char *file) { +bool HCache_check(const char *file) +{ struct stat bufa, bufb; FILE *first, *second; char s_path[255], dT[1]; time_t rtime; - if( !(first = fopen(file,"rb")) ) + if (!(first = fopen(file,"rb"))) return false; - if( file[0] == '.' && file[1] == '/' ) + if (file[0] == '.' && file[1] == '/') file += 2; - else if( file[0] == '.' ) + else if (file[0] == '.') file++; snprintf(s_path, 255, "./cache/%s", file); - if( !(second = fopen(s_path,"rb")) ) { + if (!(second = fopen(s_path,"rb"))) { fclose(first); return false; } - if( fread(dT,sizeof(dT),1,second) != 1 || fread(&rtime,sizeof(rtime),1,second) != 1 || dT[0] != HCACHE_KEY || HCache->recompile_time > rtime ) { + if (fread(dT,sizeof(dT),1,second) != 1 + || fread(&rtime,sizeof(rtime),1,second) != 1 + || dT[0] != HCACHE_KEY + || HCache->recompile_time > rtime) { fclose(first); fclose(second); return false; } - fstat(fileno(first), &bufa); - fstat(fileno(second), &bufb); - + if (fstat(fileno(first), &bufa) != 0) { + fclose(first); + fclose(second); + return false; + } fclose(first); + + if (fstat(fileno(second), &bufb) != 0) { + fclose(second); + return false; + } fclose(second); - if( bufa.st_mtime > bufb.st_mtime ) + if (bufa.st_mtime > bufb.st_mtime) return false; return true; @@ -414,24 +425,26 @@ FILE *HCache_open(const char *file, const char *opt) { hwrite(dT,sizeof(dT),1,first); hwrite(&HCache->recompile_time,sizeof(HCache->recompile_time),1,first); } - fseek(first, 20, SEEK_SET);/* skip first 20, might wanna store something else later */ + if (fseek(first, 20, SEEK_SET) != 0) { // skip first 20, might wanna store something else later + fclose(first); + return NULL; + } return first; } -void HCache_init(void) { - FILE *server; - - if( (server = fopen(SERVER_NAME,"rb")) ) { - struct stat buf; - - fstat(fileno(server), &buf); - HCache->recompile_time = buf.st_mtime; - fclose(server); - HCache->enabled = true; - } else +void HCache_init(void) +{ + struct stat buf; + if (stat(SERVER_NAME, &buf) != 0) { ShowWarning("Unable to open '%s', caching capabilities have been disabled!\n",SERVER_NAME); + return; + } + + HCache->recompile_time = buf.st_mtime; + HCache->enabled = true; } + /* transit to fread, shields vs warn_unused_result */ size_t hread(void * ptr, size_t size, size_t count, FILE * stream) { return fread(ptr, size, count, stream); |