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;
40 // open doesn't seem overridable
41 // int open (__const char *path, int flags, ...)
43 // static int (*func)(__const char *__file, int __oflag) = 0;
45 // printf("open %s\n", path);
48 // func = (int(*)(const char *path, int flags))dlsym(RTLD_NEXT, "open");
50 // result = (*func)(path, flags);
55 FILE* fopen(const char *path, const char *mode)
57 static FILE* (*func)(const char *path, const char *mode) = 0;
58 // This pointer is meaningless except on the server.
62 func = (FILE*(*)(const char *path, const char *mode))dlsym(RTLD_NEXT, "fopen");
65 if(!strncmp(path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
67 renderfarm_fs_global->lock();
68 result = renderfarm_fs_global->fopen(path, mode);
69 renderfarm_fs_global->unlock();
72 result = (*func)(path, mode);
77 FILE* fopen64(const char *path, const char *mode)
79 static FILE* (*func)(const char *path, const char *mode) = 0;
80 // This pointer is meaningless except on the server.
83 //printf("fopen64 %s\n", path);
85 func = (FILE*(*)(const char *path, const char *mode))dlsym(RTLD_NEXT, "fopen64");
88 if(!strncmp(path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
90 renderfarm_fs_global->lock();
91 result = renderfarm_fs_global->fopen(path, mode);
92 renderfarm_fs_global->unlock();
95 result = (*func)(path, mode);
102 int fclose(FILE *file)
104 static int (*func)(FILE *) = 0;
105 int result = 0, done = 0;
107 func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fclose");
108 //printf("fclose\n");
110 if(renderfarm_fs_global)
112 renderfarm_fs_global->lock();
113 if(renderfarm_fs_global->is_open(file))
115 result = renderfarm_fs_global->fclose(file);
118 renderfarm_fs_global->unlock();
121 if(!done) result = (*func)(file);
125 int fileno (FILE *stream)
127 static int (*func)(FILE *) = 0;
130 func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fileno");
131 if(renderfarm_fs_global)
133 renderfarm_fs_global->lock();
134 if(renderfarm_fs_global->is_open(stream))
136 result = renderfarm_fs_global->fileno(stream);
138 renderfarm_fs_global->unlock();
141 result = (*func)(stream);
145 // int fflush(FILE *file)
147 // static int (*func)(FILE *) = 0;
148 // int result = 0, done = 0;
150 // func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fflush");
151 // //printf("fflush\n");
153 // renderfarm_fs_global->lock();
154 // if(renderfarm_fs_global->is_open(file))
156 // result = renderfarm_fs_global->fflush(file);
159 // renderfarm_fs_global->unlock();
161 // if(!done) result = (*func)(file);
165 int remove (__const char *__filename)
167 static int (*func)(__const char *) = 0;
170 func = (int(*)(__const char *))dlsym(RTLD_NEXT, "remove");
171 //printf("remove\n");
174 if(!strncmp(__filename, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
176 renderfarm_fs_global->lock();
177 result = renderfarm_fs_global->remove(__filename);
178 renderfarm_fs_global->unlock();
181 result = (*func)(__filename);
186 int rename (__const char *__old, __const char *__new)
188 static int (*func)(__const char *, __const char *) = 0;
191 func = (int(*)(__const char *, __const char *))dlsym(RTLD_NEXT, "rename");
192 //printf("rename\n");
195 if(!strncmp(__old, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
197 renderfarm_fs_global->lock();
198 result = renderfarm_fs_global->rename(__old, __new);
199 renderfarm_fs_global->unlock();
202 result = (*func)(__old, __new);
207 int fgetc (FILE *__stream)
209 static int (*func)(FILE *) = 0;
210 int result = 0, done = 0;
212 func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fgetc");
215 if(renderfarm_fs_global)
217 renderfarm_fs_global->lock();
218 if(renderfarm_fs_global->is_open(__stream))
220 result = renderfarm_fs_global->fgetc(__stream);
223 renderfarm_fs_global->unlock();
226 if(!done) result = (*func)(__stream);
230 int getc (FILE *__stream)
232 return fgetc(__stream);
235 int fputc (int __c, FILE *__stream)
237 static int (*func)(int, FILE *) = 0;
238 int result = 0, done = 0;
240 func = (int(*)(int, FILE *))dlsym(RTLD_NEXT, "fputc");
243 if(renderfarm_fs_global)
245 renderfarm_fs_global->lock();
246 if(renderfarm_fs_global->is_open(__stream))
248 result = renderfarm_fs_global->fputc(__c, __stream);
251 renderfarm_fs_global->unlock();
254 if(!done) result = (*func)(__c, __stream);
258 int putc (int __c, FILE *__stream)
260 return fputc(__c, __stream);
263 size_t fread (void *__restrict __ptr, size_t __size,
264 size_t __n, FILE *__restrict __stream)
266 static int (*func)(void *, size_t, size_t, FILE *) = 0;
270 func = (int(*)(void *, size_t, size_t, FILE *))dlsym(RTLD_NEXT, "fread");
273 if(renderfarm_fs_global)
275 renderfarm_fs_global->lock();
276 if(renderfarm_fs_global->is_open(__stream))
278 result = renderfarm_fs_global->fread(__ptr, __size, __n, __stream);
281 renderfarm_fs_global->unlock();
284 if(!done) result = (*func)(__ptr, __size, __n, __stream);
289 size_t fwrite (__const void *__restrict __ptr, size_t __size,
290 size_t __n, FILE *__restrict __s)
292 static int (*func)(__const void *, size_t, size_t, FILE *) = 0;
296 func = (int(*)(__const void *, size_t, size_t, FILE *))dlsym(RTLD_NEXT, "fwrite");
297 //printf("fwrite\n");
299 if(renderfarm_fs_global)
301 renderfarm_fs_global->lock();
302 if(renderfarm_fs_global->is_open(__s))
304 result = renderfarm_fs_global->fwrite(__ptr, __size, __n, __s);
307 renderfarm_fs_global->unlock();
310 if(!done) result = (*func)(__ptr, __size, __n, __s);
315 int fseek (FILE *__stream, long int __off, int __whence)
317 static int (*func)(FILE *, long int, int) = 0;
321 func = (int(*)(FILE *, long int, int))dlsym(RTLD_NEXT, "fseek");
324 if(renderfarm_fs_global)
326 renderfarm_fs_global->lock();
327 if(renderfarm_fs_global->is_open(__stream))
329 result = renderfarm_fs_global->fseek(__stream, __off, __whence);
332 renderfarm_fs_global->unlock();
335 if(!done) result = (*func)(__stream, __off, __whence);
340 int fseeko64 (FILE *__stream, __off64_t __off, int __whence)
342 static int (*func)(FILE *, __off64_t, int) = 0;
346 func = (int(*)(FILE *, __off64_t, int))dlsym(RTLD_NEXT, "fseeko64");
347 //printf("fseeko64\n");
349 if(renderfarm_fs_global)
351 renderfarm_fs_global->lock();
352 if(renderfarm_fs_global->is_open(__stream))
354 result = renderfarm_fs_global->fseek(__stream, __off, __whence);
357 renderfarm_fs_global->unlock();
360 if(!done) result = (*func)(__stream, __off, __whence);
365 long int ftell (FILE *__stream)
367 static long int (*func)(FILE *) = 0;
371 func = (long int(*)(FILE *))dlsym(RTLD_NEXT, "ftell");
374 if(renderfarm_fs_global)
376 renderfarm_fs_global->lock();
377 if(renderfarm_fs_global->is_open(__stream))
379 result = renderfarm_fs_global->ftell(__stream);
382 renderfarm_fs_global->unlock();
385 if(!done) result = (*func)(__stream);
390 __off64_t ftello64 (FILE *__stream)
392 static __off64_t (*func)(FILE *) = 0;
393 __off64_t result = 0;
396 func = (__off64_t(*)(FILE *))dlsym(RTLD_NEXT, "ftello64");
398 if(renderfarm_fs_global)
400 renderfarm_fs_global->lock();
401 if(renderfarm_fs_global->is_open(__stream))
403 result = renderfarm_fs_global->ftell(__stream);
406 renderfarm_fs_global->unlock();
409 if(!done) result = (*func)(__stream);
412 return (*func)(__stream);
416 // Glibc inlines the stat functions and redirects them to __xstat functions
417 int __xstat (int __ver, __const char *__filename,
418 struct stat *__stat_buf)
420 static int (*func)(int __ver, __const char *__filename,
421 struct stat *__stat_buf) = 0;
423 // This pointer is meaningless except on the server.
427 func = (int(*)(int __ver, __const char *__filename,
428 struct stat *__stat_buf))dlsym(RTLD_NEXT, "__xstat");
431 if(!strncmp(__filename, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
433 renderfarm_fs_global->lock();
434 result = renderfarm_fs_global->stat(__filename, __stat_buf);
435 renderfarm_fs_global->unlock();
439 result = (*func)(__ver, __filename, __stat_buf);
445 int __xstat64 (int __ver, __const char *__filename,
446 struct stat64 *__stat_buf)
448 static int (*func)(int __ver, __const char *__restrict __file,
449 struct stat64 *__restrict __buf) = 0;
450 // This pointer is meaningless except on the server.
454 func = (int(*)(int __ver, __const char *__restrict __file,
455 struct stat64 *__restrict __buf))dlsym(RTLD_NEXT, "__xstat64");
458 if(!strncmp(__filename, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
460 renderfarm_fs_global->lock();
461 result = renderfarm_fs_global->stat64(__filename, __stat_buf);
462 renderfarm_fs_global->unlock();
465 result = (*func)(__ver, __filename, __stat_buf);
470 char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
472 static char* (*func)(char *__restrict __s, int __n, FILE *__restrict __stream) = 0;
476 func = (char*(*)(char *__restrict __s, int __n, FILE *__restrict __stream))dlsym(RTLD_NEXT, "fgets");
478 if(renderfarm_fs_global)
480 renderfarm_fs_global->lock();
481 if(renderfarm_fs_global->is_open(__stream))
483 result = renderfarm_fs_global->fgets(__s, __n, __stream);
486 renderfarm_fs_global->unlock();
489 if(!done) result = (*func)(__s, __n, __stream);
518 RenderFarmFSClient::RenderFarmFSClient(RenderFarmClientThread *client)
520 mutex_lock = new Mutex;
521 this->client = client;
524 RenderFarmFSClient::~RenderFarmFSClient()
527 // Must not access filesystem until we get here
528 renderfarm_fs_global = 0;
531 void RenderFarmFSClient::initialize()
533 renderfarm_fs_global = this;
536 void RenderFarmFSClient::lock()
541 void RenderFarmFSClient::unlock()
543 mutex_lock->unlock();
546 int RenderFarmFSClient::is_open(FILE *ptr)
548 for(int i = 0; i < files.total; i++)
549 if(files.values[i] == ptr) return 1;
553 void RenderFarmFSClient::set_open(FILE *ptr)
558 void RenderFarmFSClient::unset_open(FILE *ptr)
564 FILE* RenderFarmFSClient::fopen(const char *path, const char *mode)
566 int len = strlen(path) - strlen(RENDERFARM_FS_PREFIX) + strlen(mode) + 2;
567 char *buffer = new char[len];
569 strcpy(buffer, path + strlen(RENDERFARM_FS_PREFIX));
570 strcpy(buffer + strlen(buffer) + 1, mode);
574 if(!client->send_request_header(RENDERFARM_FOPEN,
577 if(client->write_socket(buffer, len, RENDERFARM_TIMEOUT) == len)
579 unsigned char data[8];
580 if(client->read_socket((char*)data, 8, RENDERFARM_TIMEOUT) == 8)
582 int64_t file_int64 = READ_INT64(data);
583 file = (FILE*)Units::int64_to_ptr(file_int64);
588 if(file) set_open(file);
592 printf("RenderFarmFSClient::fopen path=%s mode=%s file=%p\n", path, mode, file);
597 int RenderFarmFSClient::fclose(FILE *file)
600 unsigned char datagram[8];
602 int file_int64 = Units::ptr_to_int64(file);
603 STORE_INT64(file_int64);
606 if(!client->send_request_header(RENDERFARM_FCLOSE, 8))
608 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) == 8)
618 printf("RenderFarmFSClient::fclose file=%p\n", file);
622 int RenderFarmFSClient::fileno(FILE *file)
625 unsigned char datagram[8];
627 int file_int64 = Units::ptr_to_int64(file);
628 STORE_INT64(file_int64);
631 if(!client->send_request_header(RENDERFARM_FILENO, 8))
633 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) == 8)
635 unsigned char data[4];
636 if(client->read_socket((char*)data, 4, RENDERFARM_TIMEOUT) == 4)
638 result = READ_INT32(data);
648 printf("RenderFarmFSClient::fileno file=%p result=%d\n", file, result);
652 int RenderFarmFSClient::remove (__const char *__filename)
655 int len = strlen(__filename) + 1;
656 char *datagram = new char[len];
657 strcpy(datagram, __filename);
660 if(!client->send_request_header(RENDERFARM_REMOVE, len))
662 if(client->write_socket(datagram, len, RENDERFARM_TIMEOUT) != len)
673 printf("RenderFarmFSClient::remove path=%s\n", __filename);
677 int RenderFarmFSClient::rename (__const char *__old, __const char *__new)
680 int len = strlen(__old) + 1 + strlen(__new) + 1;
681 char *datagram = new char[len];
682 strcpy(datagram, __old);
683 strcpy(datagram + strlen(__old) + 1, __new);
686 if(!client->send_request_header(RENDERFARM_RENAME, len))
688 if(client->write_socket(datagram, len, RENDERFARM_TIMEOUT) != len)
699 printf("RenderFarmFSClient::remove old=%s new=%s\n", __old, __new);
703 int RenderFarmFSClient::fgetc (FILE *__stream)
706 unsigned char datagram[8];
708 int file_int64 = Units::ptr_to_int64(__stream);
709 STORE_INT64(file_int64);
712 if(!client->send_request_header(RENDERFARM_FGETC, 8))
714 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) != 8)
718 if(client->read_socket((char*)datagram, 1, RENDERFARM_TIMEOUT) != 1)
722 result = datagram[0];
730 printf("RenderFarmFSClient::fgetc file=%p result=%02x\n", __stream, result);
735 int RenderFarmFSClient::fputc (int __c, FILE *__stream)
738 unsigned char datagram[9];
740 int file_int64 = Units::ptr_to_int64(__stream);
741 STORE_INT64(file_int64);
745 if(!client->send_request_header(RENDERFARM_FPUTC, 9))
747 if(client->write_socket((char*)datagram, 9, RENDERFARM_TIMEOUT) != 9)
756 printf("RenderFarmFSClient::fputc file=%p result=%02x\n", __stream, result);
761 char* RenderFarmFSClient::fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
765 unsigned char datagram[12];
767 int file_int64 = Units::ptr_to_int64(__stream);
768 STORE_INT64(file_int64);
772 if(!client->send_request_header(RENDERFARM_FGETS, 12))
774 if(client->write_socket((char*)datagram, 12, RENDERFARM_TIMEOUT) == 12)
776 // fgets bytes to follow
777 if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) == 4)
780 bytes = READ_INT32(datagram);
783 if(client->read_socket((char*)__s, bytes, RENDERFARM_TIMEOUT) == bytes)
795 printf("RenderFarmFSClient::fgets file=%p string=%p size=%d bytes=%p\n",
796 __stream, __s, bytes, bytes);
802 size_t RenderFarmFSClient::fread (void *__restrict __ptr, size_t __size,
803 size_t __n, FILE *__restrict __stream)
806 unsigned char datagram[16];
808 int file_int64 = Units::ptr_to_int64(__stream);
809 STORE_INT64(file_int64);
814 if(!client->send_request_header(RENDERFARM_FREAD, 16))
816 if(client->write_socket((char*)datagram, 16, RENDERFARM_TIMEOUT) != 16)
821 if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) != 4)
826 result = READ_INT32(datagram);
827 if(client->read_socket((char*)__ptr, __size * result, RENDERFARM_TIMEOUT) !=
837 printf("RenderFarmFSClient::fread file=%p size=%d num=%d result=%d\n",
838 __stream, __size, __n, result);
843 size_t RenderFarmFSClient::fwrite (__const void *__restrict __ptr, size_t __size,
844 size_t __n, FILE *__restrict __s)
847 unsigned char datagram[16];
849 int file_int64 = Units::ptr_to_int64(__s);
850 STORE_INT64(file_int64);
855 if(!client->send_request_header(RENDERFARM_FWRITE, 16))
857 if(client->write_socket((char*)datagram, 16, RENDERFARM_TIMEOUT) != 16)
862 if(client->write_socket((char*)__ptr, __size * __n, RENDERFARM_TIMEOUT) !=
868 if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) != 4)
872 result = READ_INT32(datagram);
881 printf("RenderFarmFSClient::fwrite file=%p size=%d num=%d result=%d\n",
882 __s, __size, __n, result);
887 int RenderFarmFSClient::fseek (FILE *__stream, int64_t __off, int __whence)
890 unsigned char datagram[20];
892 int file_int64 = Units::ptr_to_int64(__stream);
893 STORE_INT64(file_int64);
895 STORE_INT32(__whence);
898 if(!client->send_request_header(RENDERFARM_FSEEK, 20))
900 if(client->write_socket((char*)datagram, 20, RENDERFARM_TIMEOUT) != 20)
904 if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) != 4)
907 result = READ_INT32(datagram);
914 printf("RenderFarmFSClient::fseek stream=%p offset=%lld whence=%d result=%d\n",
915 __stream, __off, __whence, result);
919 int64_t RenderFarmFSClient::ftell (FILE *__stream)
922 unsigned char datagram[8];
924 int file_int64 = Units::ptr_to_int64(__stream);
925 STORE_INT64(file_int64);
928 if(!client->send_request_header(RENDERFARM_FTELL, 8))
930 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) != 8)
934 if(client->read_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) != 8)
937 result = READ_INT64(datagram);
944 printf("RenderFarmFSClient::fseek stream=%p result=%lld\n",
949 int RenderFarmFSClient::stat (__const char *__restrict __file,
950 struct stat *__restrict __buf)
952 int len = strlen(__file) + 1;
956 if(!client->send_request_header(RENDERFARM_STAT, len))
958 if(client->write_socket((char*)__file + strlen(RENDERFARM_FS_PREFIX), len, RENDERFARM_TIMEOUT) == len)
960 if(client->read_socket((char*)__buf, sizeof(struct stat), RENDERFARM_TIMEOUT) == sizeof(struct stat))
974 printf("RenderFarmFSClient::stat path=%s\n", __file);
981 int RenderFarmFSClient::stat64 (__const char *__restrict __file,
982 struct stat64 *__restrict __buf)
984 int len = strlen(__file) + 1;
988 if(!client->send_request_header(RENDERFARM_STAT64, len))
990 if(client->write_socket((char*)__file + strlen(RENDERFARM_FS_PREFIX), len, RENDERFARM_TIMEOUT) == len)
992 if(client->read_socket((char*)__buf, sizeof(struct stat64), RENDERFARM_TIMEOUT) == sizeof(struct stat64))
1006 printf("RenderFarmFSClient::stat64 path=%s\n", __file);