@@ -615,6 +615,47 @@ static hFILE *hopen_fd(const char *filename, const char *mode)
615
615
return NULL ;
616
616
}
617
617
618
+ static hFILE * hpreload_fd (const char * filename , const char * mode )
619
+ {
620
+ if (!strchr (mode , 'r' ))
621
+ {
622
+ return NULL ;
623
+ }
624
+
625
+ hFILE_fd * fp = NULL ;
626
+ FILE * file = fopen (filename , mode );
627
+ if (!file ) goto error ;
628
+
629
+ fseek (file , 0 , SEEK_END );
630
+ int len = ftell (file );
631
+ fseek (file , 0 , SEEK_SET );
632
+
633
+ char * buffer = malloc (len );
634
+ if (buffer == NULL )
635
+ {
636
+ errno = ENOMEM ;
637
+ goto error ;
638
+ }
639
+ if (fread (buffer , 1 , len , file ) != len )
640
+ {
641
+ errno = EIO ;
642
+ goto error ;
643
+ }
644
+
645
+ fp = (hFILE_fd * ) hfile_init_fixed (sizeof (hFILE_fd ), mode , buffer , len , len );
646
+ if (fp == NULL ) goto error ;
647
+
648
+ fp -> fd = fileno (file );
649
+ fp -> is_socket = 0 ;
650
+ fp -> base .backend = & fd_backend ;
651
+ return & fp -> base ;
652
+
653
+ error :
654
+ if (file ) { int save = errno ; (void ) fclose (file ); errno = save ; }
655
+ hfile_destroy ((hFILE * ) fp );
656
+ return NULL ;
657
+ }
658
+
618
659
hFILE * hdopen (int fd , const char * mode )
619
660
{
620
661
hFILE_fd * fp = (hFILE_fd * ) hfile_init (sizeof (hFILE_fd ), mode , blksize (fd ));
@@ -821,6 +862,29 @@ static int init_add_plugin(void *obj, int (*init)(struct hFILE_plugin *),
821
862
return 0 ;
822
863
}
823
864
865
+ hFILE * hopenv_mem (const char * filename , const char * mode , va_list args )
866
+ {
867
+ char * buffer = va_arg (args , char * );
868
+ size_t sz = va_arg (args , size_t );
869
+ va_end (args );
870
+
871
+ hFILE_mem * fp = (hFILE_mem * ) hfile_init_fixed (sizeof (hFILE_mem ), mode , buffer , sz , sz );
872
+
873
+ fp -> base .backend = & mem_backend ;
874
+
875
+ return & fp -> base ;
876
+ }
877
+
878
+ int hfile_plugin_init_mem (struct hFILE_plugin * self )
879
+ {
880
+ // mem files are declared remote so they work with a tabix index
881
+ static const struct hFILE_scheme_handler handler =
882
+ {NULL , hfile_always_remote , "mem" , 2000 + 50 , hopenv_mem };
883
+ self -> name = "mem" ;
884
+ hfile_add_scheme_handler ("mem" , & handler );
885
+ return 0 ;
886
+ }
887
+
824
888
static void load_hfile_plugins ()
825
889
{
826
890
static const struct hFILE_scheme_handler
@@ -879,11 +943,29 @@ static hFILE *hopen_unknown_scheme(const char *fname, const char *mode)
879
943
return fp ;
880
944
}
881
945
946
+ /* A filename like "foo:bar" in which we don't recognise the scheme is
947
+ either an ordinary file or an indication of a missing or broken plugin.
948
+ Try to open it as an ordinary file; but if there's no such file, set
949
+ errno distinctively to make the plugin issue apparent. */
950
+ static hFILE * hopenv_unknown_scheme (const char * fname , const char * mode , va_list args )
951
+ {
952
+ char * method_type = va_arg (args , char * );
953
+ va_end (args );
954
+ if (!strcmp (method_type , "preload" )){
955
+ errno = EPROTONOSUPPORT ;
956
+ return NULL ;
957
+ }
958
+
959
+ hFILE * fp = hpreload_fd (fname , mode );
960
+ if (fp == NULL && errno == ENOENT ) errno = EPROTONOSUPPORT ;
961
+ return fp ;
962
+ }
963
+
882
964
/* Returns the appropriate handler, or NULL if the string isn't an URL. */
883
965
static const struct hFILE_scheme_handler * find_scheme_handler (const char * s )
884
966
{
885
967
static const struct hFILE_scheme_handler unknown_scheme =
886
- { hopen_unknown_scheme , hfile_always_local , "built-in" , 0 };
968
+ { hopen_unknown_scheme , hfile_always_local , "built-in" , 2000 + 50 , hopenv_unknown_scheme };
887
969
888
970
char scheme [12 ];
889
971
int i ;
0 commit comments