1 // Disable 64 bit indirections so we can override both functions.
2 #undef _LARGEFILE64_SOURCE
3 #undef _LARGEFILE_SOURCE
4 #undef _FILE_OFFSET_BITS
7 #include "renderfarm.h"
8 #include "renderfarmclient.h"
9 #include "renderfarmfsclient.h"
10 #include "renderfarmfsserver.inc"
24 // These are hacks to get all the file I/O libraries to transparently
25 // go over the network without rewriting them.
37 RenderFarmFSClient *renderfarm_fs_global = 0;
41 FILE* fopen(const char *path, const char *mode)
43 static FILE* (*func)(const char *path, const char *mode) = 0;
44 // This pointer is meaningless except on the server.
47 //printf("fopen %s\n", path);
49 func = (FILE*(*)(const char *path, const char *mode))dlsym(RTLD_NEXT, "fopen");
52 if(!strncmp(path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
54 renderfarm_fs_global->lock();
55 result = renderfarm_fs_global->fopen(path, mode);
56 renderfarm_fs_global->unlock();
59 result = (*func)(path, mode);
64 FILE* fopen64(const char *path, const char *mode)
66 static FILE* (*func)(const char *path, const char *mode) = 0;
67 // This pointer is meaningless except on the server.
70 //printf("fopen64 %s\n", path);
72 func = (FILE*(*)(const char *path, const char *mode))dlsym(RTLD_NEXT, "fopen64");
75 if(!strncmp(path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
77 renderfarm_fs_global->lock();
78 result = renderfarm_fs_global->fopen(path, mode);
79 renderfarm_fs_global->unlock();
82 result = (*func)(path, mode);
89 int fclose(FILE *file)
91 static int (*func)(FILE *) = 0;
92 int result = 0, done = 0;
94 func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fclose");
97 if(renderfarm_fs_global)
99 renderfarm_fs_global->lock();
100 if(renderfarm_fs_global->is_open(file))
102 result = renderfarm_fs_global->fclose(file);
105 renderfarm_fs_global->unlock();
108 if(!done) result = (*func)(file);
112 // int fflush(FILE *file)
114 // static int (*func)(FILE *) = 0;
115 // int result = 0, done = 0;
117 // func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fflush");
118 // //printf("fflush\n");
120 // renderfarm_fs_global->lock();
121 // if(renderfarm_fs_global->is_open(file))
123 // result = renderfarm_fs_global->fflush(file);
126 // renderfarm_fs_global->unlock();
128 // if(!done) result = (*func)(file);
132 int remove (__const char *__filename)
134 static int (*func)(__const char *) = 0;
137 func = (int(*)(__const char *))dlsym(RTLD_NEXT, "remove");
138 //printf("remove\n");
141 if(!strncmp(__filename, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
143 renderfarm_fs_global->lock();
144 result = renderfarm_fs_global->remove(__filename);
145 renderfarm_fs_global->unlock();
148 result = (*func)(__filename);
153 int rename (__const char *__old, __const char *__new)
155 static int (*func)(__const char *, __const char *) = 0;
158 func = (int(*)(__const char *, __const char *))dlsym(RTLD_NEXT, "rename");
159 //printf("rename\n");
162 if(!strncmp(__old, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
164 renderfarm_fs_global->lock();
165 result = renderfarm_fs_global->rename(__old, __new);
166 renderfarm_fs_global->unlock();
169 result = (*func)(__old, __new);
174 int fgetc (FILE *__stream)
176 static int (*func)(FILE *) = 0;
177 int result = 0, done = 0;
179 func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fgetc");
182 if(renderfarm_fs_global)
184 renderfarm_fs_global->lock();
185 if(renderfarm_fs_global->is_open(__stream))
187 result = renderfarm_fs_global->fgetc(__stream);
190 renderfarm_fs_global->unlock();
193 if(!done) result = (*func)(__stream);
197 int getc (FILE *__stream)
199 return fgetc(__stream);
202 int fputc (int __c, FILE *__stream)
204 static int (*func)(int, FILE *) = 0;
205 int result = 0, done = 0;
207 func = (int(*)(int, FILE *))dlsym(RTLD_NEXT, "fputc");
210 if(renderfarm_fs_global)
212 renderfarm_fs_global->lock();
213 if(renderfarm_fs_global->is_open(__stream))
215 result = renderfarm_fs_global->fputc(__c, __stream);
218 renderfarm_fs_global->unlock();
221 if(!done) result = (*func)(__c, __stream);
225 int putc (int __c, FILE *__stream)
227 return fputc(__c, __stream);
230 size_t fread (void *__restrict __ptr, size_t __size,
231 size_t __n, FILE *__restrict __stream)
233 static int (*func)(void *, size_t, size_t, FILE *) = 0;
237 func = (int(*)(void *, size_t, size_t, FILE *))dlsym(RTLD_NEXT, "fread");
240 if(renderfarm_fs_global)
242 renderfarm_fs_global->lock();
243 if(renderfarm_fs_global->is_open(__stream))
245 result = renderfarm_fs_global->fread(__ptr, __size, __n, __stream);
248 renderfarm_fs_global->unlock();
251 if(!done) result = (*func)(__ptr, __size, __n, __stream);
256 size_t fwrite (__const void *__restrict __ptr, size_t __size,
257 size_t __n, FILE *__restrict __s)
259 static int (*func)(__const void *, size_t, size_t, FILE *) = 0;
263 func = (int(*)(__const void *, size_t, size_t, FILE *))dlsym(RTLD_NEXT, "fwrite");
264 //printf("fwrite\n");
266 if(renderfarm_fs_global)
268 renderfarm_fs_global->lock();
269 if(renderfarm_fs_global->is_open(__s))
271 result = renderfarm_fs_global->fwrite(__ptr, __size, __n, __s);
274 renderfarm_fs_global->unlock();
277 if(!done) result = (*func)(__ptr, __size, __n, __s);
282 int fseek (FILE *__stream, long int __off, int __whence)
284 static int (*func)(FILE *, long int, int) = 0;
288 func = (int(*)(FILE *, long int, int))dlsym(RTLD_NEXT, "fseek");
291 if(renderfarm_fs_global)
293 renderfarm_fs_global->lock();
294 if(renderfarm_fs_global->is_open(__stream))
296 result = renderfarm_fs_global->fseek(__stream, __off, __whence);
299 renderfarm_fs_global->unlock();
302 if(!done) result = (*func)(__stream, __off, __whence);
307 int fseeko64 (FILE *__stream, __off64_t __off, int __whence)
309 static int (*func)(FILE *, __off64_t, int) = 0;
313 func = (int(*)(FILE *, __off64_t, int))dlsym(RTLD_NEXT, "fseeko64");
314 //printf("fseeko64\n");
316 if(renderfarm_fs_global)
318 renderfarm_fs_global->lock();
319 if(renderfarm_fs_global->is_open(__stream))
321 result = renderfarm_fs_global->fseek(__stream, __off, __whence);
324 renderfarm_fs_global->unlock();
327 if(!done) result = (*func)(__stream, __off, __whence);
332 long int ftell (FILE *__stream)
334 static long int (*func)(FILE *) = 0;
338 func = (long int(*)(FILE *))dlsym(RTLD_NEXT, "ftell");
341 if(renderfarm_fs_global)
343 renderfarm_fs_global->lock();
344 if(renderfarm_fs_global->is_open(__stream))
346 result = renderfarm_fs_global->ftell(__stream);
349 renderfarm_fs_global->unlock();
352 if(!done) result = (*func)(__stream);
357 __off64_t ftello64 (FILE *__stream)
359 static __off64_t (*func)(FILE *) = 0;
360 __off64_t result = 0;
363 func = (__off64_t(*)(FILE *))dlsym(RTLD_NEXT, "ftello64");
365 if(renderfarm_fs_global)
367 renderfarm_fs_global->lock();
368 if(renderfarm_fs_global->is_open(__stream))
370 result = renderfarm_fs_global->ftell(__stream);
373 renderfarm_fs_global->unlock();
376 if(!done) result = (*func)(__stream);
379 return (*func)(__stream);
382 // Glibc inlines the stat functions and redirects them to __xstat functions
383 int __xstat (int __ver, __const char *__filename,
384 struct stat *__stat_buf)
386 static int (*func)(int __ver, __const char *__filename,
387 struct stat *__stat_buf) = 0;
388 // This pointer is meaningless except on the server.
392 func = (int(*)(int __ver, __const char *__filename,
393 struct stat *__stat_buf))dlsym(RTLD_NEXT, "__xstat");
396 if(!strncmp(__filename, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
398 renderfarm_fs_global->lock();
399 result = renderfarm_fs_global->stat(__filename, __stat_buf);
400 renderfarm_fs_global->unlock();
403 result = (*func)(__ver, __filename, __stat_buf);
408 int __xstat64 (int __ver, __const char *__filename,
409 struct stat64 *__stat_buf)
411 static int (*func)(int __ver, __const char *__restrict __file,
412 struct stat64 *__restrict __buf) = 0;
413 // This pointer is meaningless except on the server.
417 func = (int(*)(int __ver, __const char *__restrict __file,
418 struct stat64 *__restrict __buf))dlsym(RTLD_NEXT, "__xstat64");
421 if(!strncmp(__filename, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
423 renderfarm_fs_global->lock();
424 result = renderfarm_fs_global->stat64(__filename, __stat_buf);
425 renderfarm_fs_global->unlock();
428 result = (*func)(__ver, __filename, __stat_buf);
433 char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
435 static char* (*func)(char *__restrict __s, int __n, FILE *__restrict __stream) = 0;
439 func = (char*(*)(char *__restrict __s, int __n, FILE *__restrict __stream))dlsym(RTLD_NEXT, "fgets");
441 if(renderfarm_fs_global)
443 renderfarm_fs_global->lock();
444 if(renderfarm_fs_global->is_open(__stream))
446 result = renderfarm_fs_global->fgets(__s, __n, __stream);
449 renderfarm_fs_global->unlock();
452 if(!done) result = (*func)(__s, __n, __stream);
481 RenderFarmFSClient::RenderFarmFSClient(RenderFarmClientThread *client)
483 mutex_lock = new Mutex;
484 this->client = client;
487 RenderFarmFSClient::~RenderFarmFSClient()
490 // Must not access filesystem until we get here
491 renderfarm_fs_global = 0;
494 void RenderFarmFSClient::initialize()
496 renderfarm_fs_global = this;
499 void RenderFarmFSClient::lock()
504 void RenderFarmFSClient::unlock()
506 mutex_lock->unlock();
509 int RenderFarmFSClient::is_open(FILE *ptr)
511 for(int i = 0; i < files.total; i++)
512 if(files.values[i] == ptr) return 1;
516 void RenderFarmFSClient::set_open(FILE *ptr)
521 void RenderFarmFSClient::unset_open(FILE *ptr)
527 FILE* RenderFarmFSClient::fopen(const char *path, const char *mode)
529 int len = strlen(path) - strlen(RENDERFARM_FS_PREFIX) + strlen(mode) + 2;
530 char *buffer = new char[len];
532 strcpy(buffer, path + strlen(RENDERFARM_FS_PREFIX));
533 strcpy(buffer + strlen(buffer) + 1, mode);
537 if(!client->send_request_header(RENDERFARM_FOPEN,
540 if(client->write_socket(buffer, len, RENDERFARM_TIMEOUT) == len)
542 unsigned char data[8];
543 if(client->read_socket((char*)data, 8, RENDERFARM_TIMEOUT) == 8)
545 int64_t file_int64 = READ_INT64(data);
546 file = (FILE*)Units::int64_to_ptr(file_int64);
551 if(file) set_open(file);
555 printf("RenderFarmFSClient::fopen path=%s mode=%s file=%p\n", path, mode, file);
560 int RenderFarmFSClient::fclose(FILE *file)
563 unsigned char datagram[8];
565 int file_int64 = Units::ptr_to_int64(file);
566 STORE_INT64(file_int64);
569 if(!client->send_request_header(RENDERFARM_FCLOSE, 8))
571 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) == 8)
581 printf("RenderFarmFSClient::fclose file=%p\n", file);
585 int RenderFarmFSClient::remove (__const char *__filename)
588 int len = strlen(__filename) + 1;
589 char *datagram = new char[len];
590 strcpy(datagram, __filename);
593 if(!client->send_request_header(RENDERFARM_REMOVE, len))
595 if(client->write_socket(datagram, len, RENDERFARM_TIMEOUT) != len)
606 printf("RenderFarmFSClient::remove path=%s\n", __filename);
610 int RenderFarmFSClient::rename (__const char *__old, __const char *__new)
613 int len = strlen(__old) + 1 + strlen(__new) + 1;
614 char *datagram = new char[len];
615 strcpy(datagram, __old);
616 strcpy(datagram + strlen(__old) + 1, __new);
619 if(!client->send_request_header(RENDERFARM_RENAME, len))
621 if(client->write_socket(datagram, len, RENDERFARM_TIMEOUT) != len)
632 printf("RenderFarmFSClient::remove old=%s new=%s\n", __old, __new);
636 int RenderFarmFSClient::fgetc (FILE *__stream)
639 unsigned char datagram[8];
641 int file_int64 = Units::ptr_to_int64(__stream);
642 STORE_INT64(file_int64);
645 if(!client->send_request_header(RENDERFARM_FGETC, 8))
647 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) != 8)
651 if(client->read_socket((char*)datagram, 1, RENDERFARM_TIMEOUT) != 1)
655 result = datagram[0];
663 printf("RenderFarmFSClient::fgetc file=%p result=%02x\n", __stream, result);
668 int RenderFarmFSClient::fputc (int __c, FILE *__stream)
671 unsigned char datagram[9];
673 int file_int64 = Units::ptr_to_int64(__stream);
674 STORE_INT64(file_int64);
678 if(!client->send_request_header(RENDERFARM_FPUTC, 9))
680 if(client->write_socket((char*)datagram, 9, RENDERFARM_TIMEOUT) != 9)
689 printf("RenderFarmFSClient::fputc file=%p result=%02x\n", __stream, result);
694 char* RenderFarmFSClient::fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
698 unsigned char datagram[12];
700 int file_int64 = Units::ptr_to_int64(__stream);
701 STORE_INT64(file_int64);
705 if(!client->send_request_header(RENDERFARM_FGETS, 12))
707 if(client->write_socket((char*)datagram, 12, RENDERFARM_TIMEOUT) == 12)
709 // fgets bytes to follow
710 if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) == 4)
713 bytes = READ_INT32(datagram);
716 if(client->read_socket((char*)__s, bytes, RENDERFARM_TIMEOUT) == bytes)
728 printf("RenderFarmFSClient::fgets file=%p string=%p size=%d bytes=%p\n",
729 __stream, __s, bytes, bytes);
735 size_t RenderFarmFSClient::fread (void *__restrict __ptr, size_t __size,
736 size_t __n, FILE *__restrict __stream)
739 unsigned char datagram[16];
741 int file_int64 = Units::ptr_to_int64(__stream);
742 STORE_INT64(file_int64);
747 if(!client->send_request_header(RENDERFARM_FREAD, 16))
749 if(client->write_socket((char*)datagram, 16, RENDERFARM_TIMEOUT) != 16)
754 if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) != 4)
759 result = READ_INT32(datagram);
760 if(client->read_socket((char*)__ptr, __size * result, RENDERFARM_TIMEOUT) !=
770 printf("RenderFarmFSClient::fread file=%p size=%d num=%d result=%d\n",
771 __stream, __size, __n, result);
776 size_t RenderFarmFSClient::fwrite (__const void *__restrict __ptr, size_t __size,
777 size_t __n, FILE *__restrict __s)
780 unsigned char datagram[16];
782 int file_int64 = Units::ptr_to_int64(__s);
783 STORE_INT64(file_int64);
788 if(!client->send_request_header(RENDERFARM_FWRITE, 16))
790 if(client->write_socket((char*)datagram, 16, RENDERFARM_TIMEOUT) != 16)
795 if(client->write_socket((char*)__ptr, __size * __n, RENDERFARM_TIMEOUT) !=
801 if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) != 4)
805 result = READ_INT32(datagram);
814 printf("RenderFarmFSClient::fwrite file=%p size=%d num=%d result=%d\n",
815 __s, __size, __n, result);
820 int RenderFarmFSClient::fseek (FILE *__stream, int64_t __off, int __whence)
823 unsigned char datagram[20];
825 int file_int64 = Units::ptr_to_int64(__stream);
826 STORE_INT64(file_int64);
828 STORE_INT32(__whence);
831 if(!client->send_request_header(RENDERFARM_FSEEK, 20))
833 if(client->write_socket((char*)datagram, 20, RENDERFARM_TIMEOUT) != 20)
837 if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) != 4)
840 result = READ_INT32(datagram);
847 printf("RenderFarmFSClient::fseek stream=%p offset=%lld whence=%d result=%d\n",
848 __stream, __off, __whence, result);
852 int64_t RenderFarmFSClient::ftell (FILE *__stream)
855 unsigned char datagram[8];
857 int file_int64 = Units::ptr_to_int64(__stream);
858 STORE_INT64(file_int64);
861 if(!client->send_request_header(RENDERFARM_FTELL, 8))
863 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) != 8)
867 if(client->read_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) != 8)
870 result = READ_INT64(datagram);
877 printf("RenderFarmFSClient::fseek stream=%p result=%lld\n",
882 int RenderFarmFSClient::stat (__const char *__restrict __file,
883 struct stat *__restrict __buf)
885 int len = strlen(__file) + 1;
889 if(!client->send_request_header(RENDERFARM_STAT, len))
891 if(client->write_socket((char*)__file + strlen(RENDERFARM_FS_PREFIX), len, RENDERFARM_TIMEOUT) == len)
893 if(client->read_socket((char*)__buf, sizeof(struct stat), RENDERFARM_TIMEOUT) == sizeof(struct stat))
907 printf("RenderFarmFSClient::stat path=%s\n", __file);
914 int RenderFarmFSClient::stat64 (__const char *__restrict __file,
915 struct stat64 *__restrict __buf)
917 int len = strlen(__file) + 1;
921 if(!client->send_request_header(RENDERFARM_STAT64, len))
923 if(client->write_socket((char*)__file + strlen(RENDERFARM_FS_PREFIX), len, RENDERFARM_TIMEOUT) == len)
925 if(client->read_socket((char*)__buf, sizeof(struct stat64), RENDERFARM_TIMEOUT) == sizeof(struct stat64))
939 printf("RenderFarmFSClient::stat64 path=%s\n", __file);