stdc.c 21 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  1. #include <stdio.h>
  2. #include <dirent.h>
  3. #if _WIN32
  4. #define _USE_32BIT_TIME_T
  5. #endif
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #if _WIN32
  9. #include <time.h>
  10. #include <direct.h>
  11. #define WIN32_LEAN_AND_MEAN
  12. #include <winsock2.h>
  13. #include <windows.h>
  14. #include <ws2tcpip.h>
  15. extern int bmx_inet_pton(int af, const char *src, void *dst);
  16. #define inet_pton bmx_inet_pton
  17. extern int _bbusew;
  18. #else
  19. #include <time.h>
  20. #include <unistd.h>
  21. #include <limits.h> //PATH_MAX
  22. #include <sys/time.h>
  23. #include <netinet/in.h>
  24. #include <sys/socket.h>
  25. #include <netdb.h>
  26. #include <arpa/inet.h>
  27. #endif
  28. #include <brl.mod/blitz.mod/blitz.h>
  29. FILE* stdin_;
  30. FILE* stdout_;
  31. FILE* stderr_;
  32. extern BBObject * pub_stdc_TAddrInfo__Create(struct addrinfo * info, int owner);
  33. extern BBArray * pub_stdc_TAddrInfo__CreateArray(int count);
  34. extern void pub_stdc_TAddrInfo__SetAtIndex(BBArray * arr, BBObject * info, int index);
  35. #if _WIN32
  36. int getchar_(){
  37. if( _bbusew ) return getwchar();
  38. return getchar();
  39. }
  40. int puts_( BBString *str ){
  41. if( _bbusew ) {
  42. BBChar *p=bbStringToWString( str );
  43. int res = _putws( p );
  44. bbMemFree(p);
  45. return res;
  46. }
  47. char *p=bbStringToCString( str );
  48. int res = puts( p );
  49. bbMemFree(p);
  50. return res;
  51. }
  52. int putenv_( BBString *str ){
  53. if( _bbusew ) {
  54. BBChar *p=bbStringToWString( str );
  55. int res = _wputenv( p );
  56. bbMemFree(p);
  57. return res;
  58. }
  59. char *p=bbStringToCString( str );
  60. int res = putenv( p );
  61. bbMemFree(p);
  62. return res;
  63. }
  64. BBString *getenv_( BBString *str ){
  65. if( _bbusew ) {
  66. BBChar *p=bbStringToWString( str );
  67. BBString * res = bbStringFromWString( _wgetenv( p ) );
  68. bbMemFree(p);
  69. return res;
  70. }
  71. char *p=bbStringToCString( str );
  72. BBString * res = bbStringFromCString( getenv( p ) );
  73. bbMemFree(res);
  74. return res;
  75. }
  76. int fputs_( BBString *str,FILE* file ){
  77. if( _bbusew ) {
  78. BBChar *p=bbStringToWString( str );
  79. int res = fputws( p,file );
  80. bbMemFree(p);
  81. return res;
  82. }
  83. char *p=bbStringToCString( str );
  84. int res = fputs( p,file );
  85. bbMemFree(p);
  86. return res;
  87. }
  88. int chdir_( BBString *path ){
  89. if( _bbusew ) {
  90. BBChar *p=bbStringToWString( path );
  91. int res = _wchdir( p );
  92. bbMemFree(p);
  93. return res;
  94. }
  95. char *p=bbStringToCString( path );
  96. int res = _chdir( p );
  97. bbMemFree(p);
  98. return res;
  99. }
  100. FILE* fopen_( BBString *file,BBString *mode ){
  101. if( _bbusew ) {
  102. BBChar *f=bbStringToWString( file );
  103. BBChar *m=bbStringToWString( mode );
  104. FILE * res = _wfopen( f, m );
  105. bbMemFree(m);
  106. bbMemFree(f);
  107. return res;
  108. }
  109. char *f=bbStringToCString( file );
  110. char *m=bbStringToCString( mode );
  111. FILE * res = fopen( f, m );
  112. bbMemFree(m);
  113. bbMemFree(f);
  114. return res;
  115. }
  116. BBString *getcwd_(){
  117. if( _bbusew ){
  118. wchar_t buf[MAX_PATH];
  119. _wgetcwd( buf,MAX_PATH );
  120. return bbStringFromWString( buf );
  121. }else{
  122. char buf[MAX_PATH];
  123. _getcwd( buf,MAX_PATH );
  124. return bbStringFromCString( buf );
  125. }
  126. return &bbEmptyString;
  127. }
  128. int chmod_( BBString *path,int mode ){
  129. if( _bbusew ) {
  130. BBChar *p=bbStringToWString( path );
  131. int res = _wchmod( p,mode );
  132. bbMemFree(p);
  133. return res;
  134. }
  135. char *p=bbStringToCString( path );
  136. int res = _chmod( p,mode );
  137. bbMemFree(p);
  138. return res;
  139. }
  140. int mkdir_( BBString *path,int mode ){
  141. if( _bbusew ) {
  142. BBChar *p=bbStringToWString( path );
  143. int res = _wmkdir( p );
  144. bbMemFree(p);
  145. return res;
  146. }
  147. char *p=bbStringToCString( path );
  148. int res = _mkdir( p );
  149. bbMemFree(p);
  150. return res;
  151. }
  152. int rmdir_( BBString *path ){
  153. if( _bbusew ) {
  154. BBChar *p=bbStringToWString( path );
  155. int res = _wrmdir( p );
  156. bbMemFree(p);
  157. return res;
  158. }
  159. char *p=bbStringToCString( path );
  160. int res = _rmdir( p );
  161. bbMemFree(p);
  162. return res;
  163. }
  164. int rename_( BBString *src,BBString *dst ){
  165. if( _bbusew ) {
  166. BBChar *s=bbStringToWString( src );
  167. BBChar *d=bbStringToWString( dst );
  168. int res = _wrename( s, d );
  169. bbMemFree(d);
  170. bbMemFree(s);
  171. return res;
  172. }
  173. char *s=bbStringToCString( src );
  174. char *d=bbStringToCString( dst );
  175. int res = rename( s, d );
  176. bbMemFree(d);
  177. bbMemFree(s);
  178. return res;
  179. }
  180. void remove_( BBString *path ){
  181. chmod_( path,0x1b6 );
  182. if( _bbusew ){
  183. BBChar *p=bbStringToWString( path );
  184. _wremove( p );
  185. bbMemFree(p);
  186. }else{
  187. char *p=bbStringToCString( path );
  188. remove( p );
  189. bbMemFree(p);
  190. }
  191. }
  192. void* opendir_( BBString *path ){
  193. if( _bbusew ) {
  194. BBChar *p=bbStringToWString( path );
  195. void * res = _wopendir( p );
  196. bbMemFree(p);
  197. return res;
  198. }
  199. char *p=bbStringToCString( path );
  200. void * res = opendir( p );
  201. bbMemFree(p);
  202. return res;
  203. }
  204. int closedir_( void* dir ){
  205. if( _bbusew ) return _wclosedir( (_WDIR*)dir );
  206. return closedir( (DIR*)dir );
  207. }
  208. BBString *readdir_( void* dir ){
  209. if( _bbusew ){
  210. struct _wdirent *t=_wreaddir( (_WDIR*)dir );
  211. return t ? bbStringFromWString( t->d_name ) : &bbEmptyString;
  212. }
  213. struct dirent *t=readdir( (DIR*)dir );
  214. return t ? bbStringFromCString( t->d_name ) : &bbEmptyString;
  215. }
  216. int stat_( BBString *path,int *t_mode,BBLONG *t_size,int *t_mtime,int *t_ctime ){
  217. int i;
  218. struct _stati64 st;
  219. for( i=0;i<path->length;++i ){
  220. if( path->buf[i]=='<' || path->buf[i]=='>' ) return -1;
  221. }
  222. if( _bbusew ){
  223. BBChar *p = bbStringToWString(path);
  224. if( _wstati64( p,&st ) ) {
  225. bbMemFree(p);
  226. return -1;
  227. }
  228. bbMemFree(p);
  229. }else{
  230. char *p = bbStringToCString(path);
  231. if( _stati64( p,&st ) ) {
  232. bbMemFree(p);
  233. return -1;
  234. }
  235. bbMemFree(p);
  236. }
  237. *t_mode=st.st_mode;
  238. *t_size=st.st_size;
  239. *t_mtime=st.st_mtime;
  240. *t_ctime=st.st_ctime;
  241. return 0;
  242. }
  243. int system_( BBString *cmd ){
  244. int res;
  245. PROCESS_INFORMATION pi={0};
  246. if( _bbusew ){
  247. STARTUPINFOW si={sizeof(si)};
  248. wchar_t *tmp = bbStringToWString(cmd);
  249. if( CreateProcessW( 0,tmp,0,0,1,CREATE_DEFAULT_ERROR_MODE,0,0,&si,&pi ) ){
  250. WaitForSingleObject( pi.hProcess,INFINITE );
  251. res=GetExitCodeProcess( pi.hProcess,(DWORD*)&res ) ? res : -1;
  252. CloseHandle( pi.hProcess );
  253. CloseHandle( pi.hThread );
  254. }else{
  255. res=GetLastError();
  256. }
  257. bbMemFree(tmp);
  258. } else {
  259. STARTUPINFO si={sizeof(si)};
  260. char *tmp = bbStringToCString(cmd);
  261. if( CreateProcessA( 0,tmp,0,0,1,CREATE_DEFAULT_ERROR_MODE,0,0,&si,&pi ) ){
  262. WaitForSingleObject( pi.hProcess,INFINITE );
  263. res=GetExitCodeProcess( pi.hProcess,(DWORD*)&res ) ? res : -1;
  264. CloseHandle( pi.hProcess );
  265. CloseHandle( pi.hThread );
  266. }else{
  267. res=GetLastError();
  268. }
  269. bbMemFree(tmp);
  270. }
  271. return res;
  272. }
  273. int fseek_( FILE* stream, BBLONG offset, int origin ) {
  274. // flush stream when using _fileno
  275. fflush(stream);
  276. int f = _fileno(stream);
  277. return (_lseeki64(f, offset, origin) >= 0) ? 0 : 1;
  278. }
  279. BBLONG ftell_( FILE* stream ) {
  280. // flush stream when using _fileno
  281. fflush(stream);
  282. int f = _fileno(stream);
  283. return _telli64(f);
  284. }
  285. int ftruncate_(FILE* stream, BBLONG size) {
  286. return _chsize_s(fileno(stream), size);
  287. }
  288. int clock_gettime_(int id, struct timespec * spec) {
  289. __int64 ftime;
  290. GetSystemTimeAsFileTime((FILETIME*)&ftime);
  291. ftime -= 116444736000000000LL;
  292. spec->tv_sec = ftime / 10000000LL;
  293. spec->tv_nsec = ftime % 10000000LL *100;
  294. return 0;
  295. }
  296. #else
  297. int getchar_(){
  298. return getchar();
  299. }
  300. int puts_( BBString *str ){
  301. char *p = bbStringToUTF8String( str );
  302. int res = puts( p );
  303. bbMemFree(p);
  304. return res;
  305. }
  306. int putenv_( BBString *str ){
  307. char *t=bbStringToUTF8String( str );
  308. char *p=(char*)malloc( strlen(t)+1 );
  309. strcpy( p,t );
  310. bbMemFree(t);
  311. return putenv( p );
  312. }
  313. BBString *getenv_( BBString *str ){
  314. char *p = bbStringToUTF8String( str );
  315. BBString * res = bbStringFromUTF8String( getenv( p ) );
  316. bbMemFree(p);
  317. return res;
  318. }
  319. FILE* fopen_( BBString *file,BBString *mode ){
  320. char *f = bbStringToUTF8String( file );
  321. char *m = bbStringToUTF8String( mode );
  322. FILE * res = fopen( f, m );
  323. bbMemFree(m);
  324. bbMemFree(f);
  325. return res;
  326. }
  327. int fputs_( BBString *str,FILE* file ){
  328. char *p = bbStringToUTF8String( str );
  329. int res = fputs( p,file );
  330. bbMemFree(p);
  331. return res;
  332. }
  333. int chdir_( BBString *path ){
  334. char *p = bbStringToUTF8String( path );
  335. int res = chdir( p );
  336. bbMemFree(p);
  337. return res;
  338. }
  339. BBString *getcwd_(){
  340. char buf[PATH_MAX];
  341. getcwd( buf,PATH_MAX );
  342. return bbStringFromUTF8String( buf );
  343. }
  344. int chmod_( BBString *path,int mode ){
  345. char *p = bbStringToUTF8String( path );
  346. int res = chmod( p, mode );
  347. bbMemFree(p);
  348. return res;
  349. }
  350. int mkdir_( BBString *path,int mode ){
  351. char *p = bbStringToUTF8String( path );
  352. int res = mkdir( p, mode );
  353. bbMemFree(p);
  354. return res;
  355. }
  356. int rmdir_( BBString *path ){
  357. char *p = bbStringToUTF8String( path );
  358. int res = rmdir( p );
  359. bbMemFree(p);
  360. return res;
  361. }
  362. int rename_( BBString *src,BBString *dst ){
  363. char *s = bbStringToUTF8String( src );
  364. char *d = bbStringToUTF8String( dst );
  365. int res = rename( s, d );
  366. bbMemFree(d);
  367. bbMemFree(s);
  368. return res;
  369. }
  370. int remove_( BBString *path ){
  371. char *p = bbStringToUTF8String( path );
  372. int res = remove( p );
  373. bbMemFree(p);
  374. return res;
  375. }
  376. DIR* opendir_( BBString *path ){
  377. char *p = bbStringToUTF8String( path );
  378. DIR * res = opendir( p );
  379. bbMemFree(p);
  380. return res;
  381. }
  382. BBString *readdir_( DIR* dir ){
  383. struct dirent *t=readdir( dir );
  384. return t ? bbStringFromUTF8String( t->d_name ) : &bbEmptyString;
  385. }
  386. int closedir_( DIR* dir ){
  387. return closedir( dir );
  388. }
  389. int stat_( BBString *path,int *t_mode,BBLONG *t_size,int *t_mtime,int *t_ctime ){
  390. struct stat st;
  391. char *p = bbStringToUTF8String( path );
  392. if( stat( p,&st ) ) {
  393. bbMemFree(p);
  394. return -1;
  395. }
  396. bbMemFree(p);
  397. *t_mode=st.st_mode;
  398. *t_size=st.st_size;
  399. *t_mtime=st.st_mtime;
  400. *t_ctime=st.st_ctime;
  401. return 0;
  402. }
  403. int system_( BBString *cmd ){
  404. char *p = bbStringToUTF8String( cmd );
  405. int res = system( p );
  406. bbMemFree(p);
  407. return res;
  408. }
  409. int fseek_( FILE* stream, BBLONG offset, int origin ) {
  410. return fseeko(stream, offset, origin);
  411. }
  412. BBLONG ftell_( FILE* stream ) {
  413. return ftello(stream);
  414. }
  415. int ftruncate_(FILE* stream, BBLONG size) {
  416. return ftruncate(fileno(stream), size);
  417. }
  418. #ifndef __APPLE__
  419. int clock_gettime_(int id, struct timespec * spec) {
  420. return clock_gettime(id, spec);
  421. }
  422. #endif
  423. #endif
  424. #ifdef __APPLE__
  425. #include <mach/mach_time.h>
  426. BBULONG mach_absolute_time_ns() {
  427. static mach_timebase_info_data_t s_timebase_info;
  428. static int inited = 0;
  429. if (!inited) {
  430. mach_timebase_info(&s_timebase_info);
  431. };
  432. return (mach_absolute_time() * s_timebase_info.numer) / s_timebase_info.denom;
  433. }
  434. #endif
  435. int fclose_( FILE* stream ) {
  436. return fclose(stream);
  437. }
  438. int feof_(FILE* stream) {
  439. return feof(stream);
  440. }
  441. int fflush_( FILE* stream ) {
  442. return fflush(stream);
  443. }
  444. int htons_( int n ){
  445. return htons( n );
  446. }
  447. int ntohs_( int n ){
  448. return ntohs( n );
  449. }
  450. int htonl_( int n ){
  451. return htonl( n );
  452. }
  453. int ntohl_( int n ){
  454. return ntohl( n );
  455. }
  456. int socket_( int addr_type,int comm_type,int protocol ){
  457. #if _WIN32
  458. SOCKET s = socket( addr_type,comm_type,protocol );
  459. return (s != INVALID_SOCKET) ? s :-1;
  460. #else
  461. return socket( addr_type,comm_type,protocol );
  462. #endif
  463. }
  464. void closesocket_( int s ){
  465. #if _WIN32
  466. closesocket( s );
  467. #else
  468. close( s );
  469. #endif
  470. }
  471. int bmx_stdc_convertAFFamily(int family) {
  472. switch (family) {
  473. case 2:
  474. return AF_INET;
  475. case 10:
  476. return AF_INET6;
  477. }
  478. // unmapped
  479. return family;
  480. }
  481. int bind_( int socket,int addr_type,int port ){
  482. int r;
  483. // if ( addr_type!=AF_INET ) return -1;
  484. switch(addr_type) {
  485. case AF_INET:
  486. {
  487. struct sockaddr_in sa;
  488. memset( &sa,0,sizeof(sa) );
  489. sa.sin_family= bmx_stdc_convertAFFamily(addr_type);
  490. sa.sin_addr.s_addr=htonl(INADDR_ANY);
  491. sa.sin_port=htons( port );
  492. return bind( socket,(void*)&sa,sizeof(sa) );
  493. }
  494. case AF_INET6:
  495. {
  496. struct sockaddr_in6 sa;
  497. memset( &sa,0,sizeof(sa) );
  498. sa.sin6_family= bmx_stdc_convertAFFamily(addr_type);
  499. sa.sin6_addr=in6addr_any;
  500. sa.sin6_port=htons( port );
  501. return bind( socket,(void*)&sa,sizeof(sa) );
  502. }
  503. default:
  504. return -1;
  505. }
  506. }
  507. int bmx_stdc_bind_info(int socket, struct addrinfo * info) {
  508. return bind(socket, info->ai_addr, info->ai_addrlen);
  509. }
  510. char *gethostbyaddr_( void *addr,int addr_len,int addr_type ){
  511. return NULL;
  512. //struct hostent *e=gethostbyaddr( addr,addr_len,addr_type );
  513. //return e ? e->h_name : 0;
  514. }
  515. BBARRAY getaddrinfo_hints(BBString *name, BBString *service, struct addrinfo * hints) {
  516. struct addrinfo * info;
  517. struct addrinfo * ip;
  518. char * n = bbStringToUTF8String(name);
  519. char * s = 0;
  520. if (service != &bbEmptyString) {
  521. s = bbStringToUTF8String(service);
  522. }
  523. int res = getaddrinfo(n, s, hints, &info);
  524. bbMemFree(s);
  525. bbMemFree(n);
  526. if (res != 0) {
  527. return &bbEmptyArray;
  528. }
  529. int count = 0;
  530. for (ip = info; ip != NULL; ip = ip->ai_next) {
  531. count++;
  532. }
  533. BBArray * arr = pub_stdc_TAddrInfo__CreateArray(count);
  534. count = 0;
  535. for (ip = info; ip != NULL; ip = ip->ai_next) {
  536. BBObject * obj = pub_stdc_TAddrInfo__Create(ip, count == 0);
  537. pub_stdc_TAddrInfo__SetAtIndex(arr, obj, count);
  538. count++;
  539. }
  540. return arr;
  541. }
  542. BBARRAY getaddrinfo_(BBString *name, BBString *service, int family) {
  543. struct addrinfo hints;
  544. memset(&hints, 0, sizeof(struct addrinfo));
  545. hints.ai_family = bmx_stdc_convertAFFamily(family);
  546. return getaddrinfo_hints(name, service, &hints);
  547. }
  548. struct addrinfo * bmx_stdc_addrinfo_new() {
  549. return (struct addrinfo *)calloc(1, sizeof(struct addrinfo));
  550. }
  551. void freeaddrinfo_(struct addrinfo * info ) {
  552. freeaddrinfo(info);
  553. }
  554. int connect_( int socket, struct addrinfo * info ){
  555. return connect( socket, info->ai_addr, info->ai_addrlen);
  556. }
  557. int listen_( int socket,int backlog ){
  558. return listen( socket,backlog );
  559. }
  560. int accept_( int socket,const char *addr,unsigned int *addr_len ){
  561. return accept( socket,(void*)addr,addr_len );
  562. }
  563. int bmx_stdc_accept_(int socket, struct sockaddr_storage * storage) {
  564. if (storage) {
  565. int size = sizeof(struct sockaddr_storage );
  566. return accept(socket, (struct sockaddr *)storage, &size);
  567. } else {
  568. return accept(socket, NULL, NULL);
  569. }
  570. }
  571. int select_( int n_read,int *r_socks,int n_write,int *w_socks,int n_except,int *e_socks,int millis ){
  572. int i,n,r;
  573. struct timeval tv,*tvp;
  574. fd_set r_set,w_set,e_set;
  575. n=-1;
  576. FD_ZERO( &r_set );
  577. for( i=0;i<n_read;++i ){
  578. FD_SET( r_socks[i],&r_set );
  579. if( r_socks[i]>n ) n=r_socks[i];
  580. }
  581. FD_ZERO( &w_set );
  582. for( i=0;i<n_write;++i ){
  583. FD_SET( w_socks[i],&w_set );
  584. if( w_socks[i]>n ) n=w_socks[i];
  585. }
  586. FD_ZERO( &e_set );
  587. for( i=0;i<n_except;++i ){
  588. FD_SET( e_socks[i],&e_set );
  589. if( e_socks[i]>n ) n=e_socks[i];
  590. }
  591. if( millis<0 ){
  592. tvp=0;
  593. }else{
  594. tv.tv_sec=millis/1000;
  595. tv.tv_usec=(millis%1000)*1000;
  596. tvp=&tv;
  597. }
  598. r=select( n+1,&r_set,&w_set,&e_set,tvp );
  599. if( r<0 ) return r;
  600. for( i=0;i<n_read;++i ){
  601. if( !FD_ISSET(r_socks[i],&r_set) ) r_socks[i]=0;
  602. }
  603. for( i=0;i<n_write;++i ){
  604. if( !FD_ISSET(w_socks[i],&w_set) ) w_socks[i]=0;
  605. }
  606. for( i=0;i<n_except;++i ){
  607. if( !FD_ISSET(e_socks[i],&e_set) ) e_socks[i]=0;
  608. }
  609. return r;
  610. }
  611. ssize_t send_( int socket,const char *buf,size_t size,int flags ){
  612. return send( socket,buf,size,flags );
  613. }
  614. int sendto_( int socket,const char *buf,int size,int flags,const char * dest_ip,int dest_port, int addr_type ){
  615. addr_type = bmx_stdc_convertAFFamily(addr_type);
  616. switch (addr_type) {
  617. case AF_INET:
  618. {
  619. struct sockaddr_in sa;
  620. memset( &sa,0,sizeof(sa) );
  621. sa.sin_family=AF_INET;
  622. #ifdef _WIN32
  623. sa.sin_addr.s_addr=inet_addr( dest_ip );
  624. #else
  625. inet_pton(AF_INET, dest_ip, &(sa.sin_addr));
  626. #endif
  627. // memcpy( &sa.sin_addr,dest_ip,4 );
  628. sa.sin_port=htons( dest_port );
  629. return sendto( socket,buf,size,flags,(void*)&sa,sizeof(sa));
  630. }
  631. case AF_INET6:
  632. {
  633. struct sockaddr_in6 sa;
  634. memset( &sa,0,sizeof(sa) );
  635. sa.sin6_family=AF_INET6;
  636. sa.sin6_port=htons( dest_port );
  637. memcpy( &sa.sin6_addr, dest_ip,16 );
  638. return sendto( socket,buf,size,flags,(void*)&sa,sizeof(sa));
  639. }
  640. }
  641. return 0;
  642. }
  643. ssize_t recv_( int socket,char *buf,size_t size,int flags ){
  644. return recv( socket,buf,size,flags );
  645. }
  646. int recvfrom_( int socket,char *buf,int size,int flags,int *_ip,int *_port){
  647. struct sockaddr_in sa;
  648. int sasize;
  649. int count;
  650. memset( &sa,0,sizeof(sa) );
  651. sasize=sizeof(sa);
  652. count=recvfrom(socket,buf,size,flags,(void*)&sa,&sasize);
  653. *_ip=ntohl_(sa.sin_addr.s_addr);
  654. *_port=ntohs_(sa.sin_port);
  655. return count;
  656. }
  657. int setsockopt_( int socket,int level,int optname,const void *optval,int count){
  658. return setsockopt( socket,level,optname,optval,count);
  659. }
  660. int getsockopt_( int socket,int level,int optname,void *optval,int *count){
  661. return getsockopt( socket,level,optname,optval,count);
  662. }
  663. int shutdown_( int socket,int how ){
  664. return shutdown( socket,how );
  665. }
  666. int getsockname_( int socket,void *addr,int *len ){
  667. return getsockname( socket,addr,len );
  668. }
  669. int getpeername_( int socket,void *addr,int *len ){
  670. return getpeername( socket,addr,len );
  671. }
  672. int time_( void *ttime ){
  673. return (int)time( (time_t*)ttime );
  674. }
  675. void *localtime_( void *ttime ){
  676. return localtime( (time_t*)ttime );
  677. }
  678. int strftime_( char *buf,int size,BBString *fmt,void *ttime ){
  679. char *p = bbStringToCString( fmt );
  680. int res = strftime( buf,size,p,ttime );
  681. bbMemFree(p);
  682. return res;
  683. }
  684. int bmx_stdc_addrinfo_flags(struct addrinfo * info) {
  685. return info->ai_flags;
  686. }
  687. int bmx_stdc_addrinfo_family(struct addrinfo * info) {
  688. return info->ai_family;
  689. }
  690. int bmx_stdc_addrinfo_socktype(struct addrinfo * info) {
  691. return info->ai_socktype;
  692. }
  693. int bmx_stdc_addrinfo_protocol(struct addrinfo * info) {
  694. return info->ai_protocol;
  695. }
  696. int bmx_stdc_addrinfo_addrlen(struct addrinfo * info) {
  697. return info->ai_addrlen;
  698. }
  699. struct sockaddr * bmx_stdc_addrinfo_addr(struct addrinfo * info) {
  700. return info->ai_addr;
  701. }
  702. BBString * bmx_stdc_addrinfo_canonname(struct addrinfo * info) {
  703. return bbStringFromUTF8String(info->ai_canonname);
  704. }
  705. void bmx_stdc_addrinfo_setflags(struct addrinfo * info, int flags) {
  706. info->ai_flags = flags;
  707. }
  708. void bmx_stdc_addrinfo_setfamily(struct addrinfo * info, int family) {
  709. info->ai_family = bmx_stdc_convertAFFamily(family);
  710. }
  711. void bmx_stdc_addrinfo_setsocktype(struct addrinfo * info, int sockType) {
  712. info->ai_socktype = sockType;
  713. }
  714. void bmx_stdc_addrinfo_setprotocol(struct addrinfo * info, int protocol) {
  715. info->ai_protocol = protocol;
  716. }
  717. int bmx_stdc_convertNIFlags(int flags) {
  718. int niFlags = 0;
  719. if (flags & 0x0001) {
  720. niFlags |= NI_DGRAM;
  721. }
  722. if (flags & 0x0002) {
  723. niFlags |= NI_NAMEREQD;
  724. }
  725. if (flags & 0x0004) {
  726. niFlags |= NI_NOFQDN;
  727. }
  728. if (flags & 0x0008) {
  729. niFlags |= NI_NUMERICHOST;
  730. }
  731. if (flags & 0x0010) {
  732. niFlags |= NI_NUMERICSERV;
  733. }
  734. return niFlags;
  735. }
  736. BBString * bmx_stdc_addrinfo_hostname(struct addrinfo * info, int flags) {
  737. char host[256];
  738. int res = getnameinfo(info->ai_addr, info->ai_addrlen, host, 256, 0, 0, bmx_stdc_convertNIFlags(flags));
  739. if (res != 0) {
  740. return &bbEmptyString;
  741. }
  742. return bbStringFromUTF8String(host);
  743. }
  744. int inet_pton_(int family, BBString * src, void * dst) {
  745. char * s = bbStringToCString(src);
  746. int res = inet_pton(bmx_stdc_convertAFFamily(family), s, dst);
  747. bbMemFree(s);
  748. return res;
  749. }
  750. struct sockaddr_storage * bmx_stdc_sockaddrestorage_new() {
  751. return calloc(1, sizeof(struct sockaddr_storage));
  752. }
  753. BBString * bmx_stdc_sockaddrestorage_address(struct sockaddr_storage * storage) {
  754. BBString * address = &bbEmptyString;
  755. #if _WIN32
  756. TCHAR add[256];
  757. typedef LPTSTR (__stdcall RTLIPV6ADDRESSTOSTRING)(const IN6_ADDR*, PTSTR);
  758. typedef LPTSTR (__stdcall RTLIPV4ADDRESSTOSTRING)(const IN_ADDR*, PTSTR);
  759. HMODULE ntdll = GetModuleHandle("NTDLL.DLL");
  760. if (storage->ss_family == AF_INET) {
  761. RTLIPV4ADDRESSTOSTRING* RtlIpv4AddressToStringFunc = (RTLIPV4ADDRESSTOSTRING*)GetProcAddress(ntdll, "RtlIpv4AddressToStringW");
  762. RtlIpv4AddressToStringFunc(&((struct sockaddr_in*)storage)->sin_addr, add);
  763. } else {
  764. RTLIPV6ADDRESSTOSTRING* RtlIpv6AddressToStringFunc = (RTLIPV6ADDRESSTOSTRING*)GetProcAddress(ntdll, "RtlIpv6AddressToStringW");
  765. RtlIpv6AddressToStringFunc(&((struct sockaddr_in6*)storage)->sin6_addr, add);
  766. }
  767. address = bbStringFromWString((BBChar*)add);
  768. #else
  769. char add[256];
  770. if (storage->ss_family == AF_INET) {
  771. inet_ntop(storage->ss_family, &((struct sockaddr_in*)storage)->sin_addr, add, sizeof(add));
  772. } else {
  773. inet_ntop(storage->ss_family, &((struct sockaddr_in6*)storage)->sin6_addr, add, sizeof(add));
  774. }
  775. address = bbStringFromCString(add);
  776. #endif
  777. return address;
  778. }
  779. int bmx_stdc_getsockname(int socket, int * port, BBSTRING * address) {
  780. struct sockaddr_storage storage;
  781. int len = sizeof(struct sockaddr_storage);
  782. int res = getsockname(socket, (struct sockaddr *)&storage, &len);
  783. if (res >= 0) {
  784. if (storage.ss_family == AF_INET) {
  785. *port = ntohs(((struct sockaddr_in*)&storage)->sin_port);
  786. } else {
  787. *port = ntohs(((struct sockaddr_in6*)&storage)->sin6_port);
  788. }
  789. *address = bmx_stdc_sockaddrestorage_address(&storage);
  790. }
  791. return res;
  792. }
  793. int bmx_stdc_getpeername(int socket, int * port, BBSTRING * address) {
  794. struct sockaddr_storage storage;
  795. int len = sizeof(struct sockaddr_storage);
  796. int res = getpeername(socket, (struct sockaddr *)&storage, &len);
  797. if (res >= 0) {
  798. if (storage.ss_family == AF_INET) {
  799. *port = ntohs(((struct sockaddr_in*)&storage)->sin_port);
  800. } else {
  801. *port = ntohs(((struct sockaddr_in6*)&storage)->sin6_port);
  802. }
  803. *address = bmx_stdc_sockaddrestorage_address(&storage);
  804. }
  805. return res;
  806. }
  807. #if _WIN32
  808. static void CleanupWSA(){
  809. WSACleanup();
  810. }
  811. #endif
  812. void bb_stdc_Startup(){
  813. #if _WIN32
  814. WSADATA ws;
  815. WSAStartup( MAKEWORD(2, 2),&ws );
  816. atexit( CleanupWSA );
  817. #endif
  818. stdin_=stdin;
  819. stdout_=stdout;
  820. stderr_=stderr;
  821. }