from my previsou question Why does module failed to load? (/dev/scull0 : no such device or address) I managed to load the module via /sbin/insmod, but after that, I have log out the dmesg:
[ 2765.707018] scull: loading out-of-tree module taints kernel.
[ 2765.707106] scull: module verification failed: signature and/or required key missing - tainting kernel
[ 2765.707929] Passed scull_init_module at 41 (debug info - successful load of init module)
[ 6027.843914] acer_wmi: Unknown function number - 8 - 1
[ 7347.683312] stack segment: 0000 [#1] SMP PTI
[ 7347.683323] CPU: 3 PID: 15280 Comm: rmmod Tainted: G OE 4.19.0-9-amd64 #1 Debian 4.19.118-2
[ 7347.683326] Hardware name: Acer Swift SF314-52/Suntory_KL, BIOS V1.08 11/28/2017
/* start of the problem: */
[ 7347.683335] RIP: 0010:scull_trim+0x3a/0xa0 [scull]
[ 7347.683339] Code: 44 8b 77 0c 48 8b 2f 45 8d 66 ff 49 c1 e4 03 48 85 ed 75 16 eb 4b 48 8b 5d 08 48 89 ef e8 7e 38 f1 e1 48 89 dd 48 85 db 74 37 <48> 8b 7d 00 48 85 ff 74 e3 45 85 f6 7e 1a 31 db eb 04 48 83 c3 08
/*... output of all registers ...*/
[ 7347.683372] Call Trace:
[ 7347.683382] cleanup_module+0x44/0x80 [scull]
[ 7347.683391] __x64_sys_delete_module+0x190/0x2e0
[ 7347.683399] do_syscall_64+0x53/0x110
[ 7347.683405] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 7347.683530] ---[ end trace c4b4a1cdb428d4b3 ]---
[ 7347.885914] RIP: 0010:scull_trim+0x3a/0xa0 [scull]
... /* again */ ...
Here I can observer, the mess is caused by the scull_trim (source below), and kernel trigger strace to resolve it (or does kernel call Call Trace: when something goes bad in kernel?).
scull_trim:
/*main structure */
struct scull_dev {
struct scull_qset *data; /*quantum repre*/
int quantum; /*in bytes*/
int qset; /*array size*/
unsigned long size; /*total bytes in device*/
struct cdev cdev; /*Char device structure*/
};
/*representation of quantum*/
struct scull_qset {
void **data;
struct scull_qset *next;
};
/*-------------------------------------------------------------------------------------*/
int scull_trim(struct scull_dev *dev) {
struct scull_qset *next, *dptr; /* next for loop, dptr = data pointer (index in loop) */
int qset = dev->qset; /* get size of arrat */
int i; /*index for second loop for quantum bytes */
for(dptr = dev->data /*struct scull_qset*/; dptr ; dptr = next){
if (dptr->data /*array of quantum*/) {
for(i=0; i<qset; i++){
kfree(dptr->data[i]); /*free each byte of array data[i]*/
}
kfree(dptr->data); /*free array pointer itself*/
dptr->data = NULL; /*set array pointer to null pointer to avoid garbage*/
}
next = dptr->next;
kfree(dptr); /* free pointer itself */
}
//setting new attributes for cleared dev
dev->size = 0;
dev->quantum = scull_quantum;
dev->qset = scull_qset;
dev->data = NULL;
return 0;
}
The function scull_trim is basically from linux device driver, 3 edition, And the function's intend is to get rid of all bytes from the device before open method is called. But why does it caused the dmesg error in that, kernel had to call strace to resolve it?
EDIT:
Because it is nearly impossible to resolve the problem, I am adding source (as well as dmesg dump) from github:
repo:scull device. Please visit it to resolve the issue.
Related
I am working with one ZigBee module based on 32-bit ARM Cortex-M3. But my question is not related to ZigBee protocol itself. I have access to the source code of application layer only which should be enough for my purposes. Lower layer (APS) passes data to application layer within APSDE-DATA.indication primitive to the following application function:
void zbpro_dataRcvdHandler(zbpro_dataInd_t *data)
{
DEBUG_PRINT(DBG_APP,"\n[APSDE-DATA.indication]\r\n");
/* Output of raw bytes string for further investigation.
* Real length is unknown, 50 is approximation.
*/
DEBUG_PRINT(DBG_APP,"Raw data: \n");
DEBUG_PRINT(DBG_APP,"----------\n");
for (int i = 0; i < 50; i++){
DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data+i));
}
DEBUG_PRINT(DBG_APP,"\n");
/* Output of APSDE-DATA.indication primitive field by field */
DEBUG_PRINT(DBG_APP,"Field by field: \n");
DEBUG_PRINT(DBG_APP,"----------------\n");
DEBUG_PRINT(DBG_APP,"Destination address: ");
for (int i = 0; i < 8; i++)
DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data->dstAddress.ieeeAddr[i]));
DEBUG_PRINT(DBG_APP,"\n");
DEBUG_PRINT(DBG_APP,"Destination address mode: 0x%02x\r\n",*((uint8_t*)data->dstAddrMode));
DEBUG_PRINT(DBG_APP,"Destination endpoint: 0x%02x\r\n",*((uint8_t*)data->dstEndPoint));
DEBUG_PRINT(DBG_APP,"Source address mode: 0x%02x\r\n",*((uint8_t*)data->dstAddrMode));
DEBUG_PRINT(DBG_APP,"Source address: ");
for (int i = 0; i < 8; i++)
DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data->srcAddress.ieeeAddr[i]));
DEBUG_PRINT(DBG_APP,"\n");
DEBUG_PRINT(DBG_APP,"Source endpoint: 0x%02x\r\n",*((uint8_t*)data->srcEndPoint));
DEBUG_PRINT(DBG_APP,"Profile Id: 0x%04x\r\n",*((uint16_t*)data->profileId));
DEBUG_PRINT(DBG_APP,"Cluster Id: 0x%04x\r\n",*((uint16_t*)data->clusterId));
DEBUG_PRINT(DBG_APP,"Message length: 0x%02x\r\n",*((uint8_t*)data->messageLength));
DEBUG_PRINT(DBG_APP,"Flags: 0x%02x\r\n",*((uint8_t*)data->flags));
DEBUG_PRINT(DBG_APP,"Security status: 0x%02x\r\n",*((uint8_t*)data->securityStatus));
DEBUG_PRINT(DBG_APP,"Link quality: 0x%02x\r\n",*((uint8_t*)data->linkQuality));
DEBUG_PRINT(DBG_APP,"Source MAC Address: 0x%04x\r\n",*((uint16_t*)data->messageLength));
DEBUG_PRINT(DBG_APP,"Message: ");
for (int i = 0; i < 13; i++){
DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data->messageContents+i));
}
DEBUG_PRINT(DBG_APP,"\n");
bufm_deallocateBuffer((uint8_t *)data, CORE_MEM);
}
APSDE-DATA.indication primitive is implemented by following structures:
/**
* #brief type definition for address (union of short address and extended address)
*/
typedef union zbpro_address_tag {
uint16_t shortAddr;
uint8_t ieeeAddr[8];
} zbpro_address_t;
/**
* #brief apsde data indication structure
*/
PACKED struct zbpro_dataInd_tag {
zbpro_address_t dstAddress;
uint8_t dstAddrMode;
uint8_t dstEndPoint;
uint8_t srcAddrMode;
zbpro_address_t srcAddress;
uint8_t srcEndPoint;
uint16_t profileId;
uint16_t clusterId;
uint8_t messageLength;
uint8_t flags; /* bit0: broadcast or not; bit1: need aps ack or not; bit2: nwk key used; bit3: aps link key used */
uint8_t securityStatus; /* not-used, reserved for future */
uint8_t linkQuality;
uint16_t src_mac_addr;
uint8_t messageContents[1];
};
typedef PACKED struct zbpro_dataInd_tag zbpro_dataInd_t;
As a result I receive next:
[APSDE-DATA.indication]
Raw data:
---------
00 00 00 72 4c 19 40 00 02 e8 03 c2 30 02 fe ff 83 0a 00 e8 05 c1 11 00 11 08 58 40 72 4c ae 53 4d 3f 63 9f d8 51 da ca 87 a9 0b b3 7b 04 68 ca 87 a9
Field by field:
---------------
Destination address: 00 00 00 28 fa 44 34 00
Destination address mode: 0x12
Destination endpoint: 0xc2
Source address mode: 0x12
Source address: 13 01 12 07 02 bd 02 00
Source endpoint: 0xc2
Profile Id: 0xc940
Cluster Id: 0x90a0
Message length: 0x00
Flags: 0x00
Security status: 0x04
Link quality: 0x34
Source MAC Address: 0x90a0
Message: ae 53 4d 3f 63 9f d8 51 da ca 87 a9 0b
From this output I can see that while raw string has some expected values, dispatched fields are totally different. What is the reason of this behavior and how to fix it? Is it somehow related to ARM architecture or wrong type casting?
I don't have access to implementation of DEBUG_PRINT, but we can assume that it works properly.
There's no need to dereference in your DEBUG_PRINT statements, for example
DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data->dstAddress.ieeeAddr[i]));
should be simply
DEBUG_PRINT(DBG_APP,"%02x ", data->dstAddress.ieeeAddr[i]);
so on and so forth...
Consider this code:
DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data->dstAddress.ieeeAddr[i]));
Array subscripting and direct and indirect member access have higher precedence than does casting, so the third argument is equivalent to
*( (uint8_t*) (data->dstAddress.ieeeAddr[i]) )
But data->dstAddress.ieeeAddr[i] is not a pointer, it is an uint8_t. C permits you to convert it to a pointer by casting, but the result is not a pointer to the value, but rather a pointer interpretation of the value. Dereferencing it produces undefined behavior.
Similar applies to your other DEBUG_PRINT() calls.
I have a raw ECDSA signature: R and S values. I need a DER-encoded version of the signature. Is there a straightforward way to do this in openssl using the c interface?
My current attempt is to use i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp) to populate an ECDSA_SIG*. The call returns non-zero but the target buffer doesn't seem to be changed.
I'm intiailly filling my ECDSA_SIG wtih r and s values. I don't see any errors. The man page says r and s should be allocated when I call ECDSA_SIG_new
ECDSA_SIG* ec_sig = ECDSA_SIG_new();
if (NULL == BN_bin2bn(sig, 32, (ec_sig->r))) {
dumpOpenSslErrors();
}
DBG("post r :%s\n", BN_bn2hex(ec_sig->r));
if (NULL == BN_bin2bn(sig + 32, 32, (ec_sig->s))) {
dumpOpenSslErrors();
}
DBG("post s :%s\n", BN_bn2hex(ec_sig->s));
S and R are now set:
post r :397116930C282D1FCB71166A2D06728120CF2EE5CF6CCD4E2D822E8E0AE24A30
post s :9E997D4718A7603942834FBDD22A4B856FC4083704EDE62033CF1A77CB9822A9
now to make the encoded signature.
int sig_size = i2d_ECDSA_SIG(ec_sig, NULL);
if (sig_size > 255) {
DBG("signature is too large wants %d\n", sig_size);
}
DBG("post i2d:%s\n", BN_bn2hex(ec_sig->s));
s hasn't changed:
post i2d:9E997D4718A7603942834FBDD22A4B856FC4083704EDE62033CF1A77CB9822A9
At this point I have more than enough bytes ready and I set the target to all 6s so it's easy to see what changes.
unsigned char* sig_bytes = new unsigned char[256];
memset(sig_bytes, 6, 256);
sig_size = i2d_ECDSA_SIG(ec_sig, (&sig_bytes));
DBG("New size %d\n", sig_size);
DBG("post i2d:%s\n", BN_bn2hex(ec_sig->s));
hexDump("Sig ", (const byte*)sig_bytes, sig_size);
The new size is 71
New size 71 and s iis stiill the same:
`post i2d:9E997D4718A7603942834FBDD22A4B856FC4083704EDE62033CF1A77CB9822A9`
The hex dump is all 6s.
--Sig --
0x06: 0x06: 0x06: 0x06: 0x06: 0x06: 0x06: 0x06:
0x06: ...
The dump is still all 6s even though the call didn't return 0. What am I missing tying to DER encode this raw signature?
i2d_ECDSA_SIG modifies its second argument, increasing it by the size of the signature. From ecdsa.h:
/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
* (*pp += length of the DER encoded signature)).
* \param sig pointer to the ECDSA_SIG object
* \param pp pointer to a unsigned char pointer for the output or NULL
* \return the length of the DER encoded ECDSA_SIG object or 0
*/
int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
So you need to keep track of the original value of sig_bytes when you call i2d_ECDSA_SIG:
int sig_size = i2d_ECDSA_SIG(ec_sig, NULL);
unsigned char *sig_bytes = malloc(sig_size);
unsigned char *p;
memset(sig_bytes, 6, sig_size);
p = sig_bytes;
new_sig_size = i2d_ECDSA_SIG(_sig, &p);
// The value of p is now sig_bytes + sig_size, and the signature resides at sig_bytes
Output:
30 45 02 20 39 71 16 93 0C 28 2D 1F CB 71 16 6A
2D 06 72 81 20 CF 2E E5 CF 6C CD 4E 2D 82 2E 8E
0A E2 4A 30 02 21 00 9E 99 7D 47 18 A7 60 39 42
83 4F BD D2 2A 4B 85 6F C4 08 37 04 ED E6 20 33
CF 1A 77 CB 98 22 A9
I have the following issue: I want to define the clock a CPU should use during frequency transitions in the device tree rather than in the clock driver code (in this way it will be more generic). I want to define the "transition-clock" property in the device tree, something like:
232 cpu: cpu#01c20050 {
233 #clock-cells = <0>;
234 compatible = "allwinner,sun4i-a10-cpu-clk";
235 reg = <0x01c20050 0x4>;
-----
243 clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
244 transition-clock = <&osc24M>;
245 clock-output-names = "cpu";
246 };
I changed the file "drivers/clk/clkdev.c" to search this property so I can get a clk pointer and store it in a new property in the cpu clock structure. This is what I have managed so far (changes begin on line 78):
59 static struct clk *__of_clk_get(struct device_node *np, int index,
60 const char *dev_id, const char *con_id)
61 {
62 struct of_phandle_args clkspec;
63 struct clk *clk, *transition_clk;
64 struct device_node *clock_node, *transition_clock_node;
65 int rc;
66
67 if (index < 0)
68 return ERR_PTR(-EINVAL);
69
70 rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
71 &clkspec);
72 if (rc)
73 return ERR_PTR(rc);
74
75 clk = __of_clk_get_by_clkspec(&clkspec, dev_id, con_id);
76 of_node_put(clkspec.np);
77
78 clock_node = of_parse_phandle(np, "clocks", 0);
79 pr_err("-------------------- parsing node %s\n", np->name);
80 if (clock_node!=NULL) {
81 pr_err("============ Clock node found %p\n", clock_node);
82 transition_clock_node =
83 of_parse_phandle(clock_node, "transition-clock", 0);
84 if (transition_clock_node!=NULL) {
85 pr_err("============ Transition clock node found %p\n",
86 transition_clock_node);
87 transition_clk = clk_get(clock_node, 0);
88 pr_err("============ Transition clock %p\n", transition_clk);
89 }
90 }
91
92 return clk;
93 }
I get pointers to the clock node and the transition clock node, but when I try to get a clock pointer from that, I get 0xfffffffe, which looks like an error:
[ 2.540542] -------------------- parsing node cpu
[ 2.540546] ============ Clock node found eeef9520
[ 2.540550] ============ Transition clock node found eeef8934
[ 2.540555] ============ Transition clock fffffffe
I want a clock object which I can later use in
clk_set_parent(cpu_clk, cpu_clk->transition_clk)
Any ideas are welcome :)
OK, I got it figured out in the meantime and since nobody answered I'm going to provide my solution (maybe somebody else bumps into this issue):
81 if (clock_node != NULL) {
82 rc = of_parse_phandle_with_args(clock_node, "transition-clock", NULL,
83 0, &transition_clkspec);
84 of_node_put(transition_clkspec.np);
85
86 if (!rc) {
87 transition_clock = __of_clk_get_by_clkspec(&transition_clkspec,
88 dev_id, con_id);
89 clk_set_transition_parent(clk, transition_clock);
90 }
91 }
So, the solution is to get an object of type "of_phandle_args" and get the clock from there using __of_clk_get_by_clkspec.
(the clk_set_transition_parent function is defined somewhere else and it does exactly what it's name suggests)
I'm attempting to extract data from a struct sk_buff, but have not received the output I am expecting. The frame in question is 34 bytes; a 14-byte Ethernet header wrapped around an 8-byte (experimental protocol) header:
struct monitoring_hdr {
u8 version;
u8 type;
u8 reserved;
u8 haddr_len;
u32 clock;
} __packed;
After this header, there are two, variable-length hardware addresses (their lengths are dictated by the haddr_len field above). In the example here, they are both 6 bytes long.
The following code extracts the header (the struct) correctly, but not the two MAC addresses that follow.
Sender side:
...
skb = alloc_skb(mtu, GFP_ATOMIC);
if (unlikely(!skb))
return;
skb_reserve(skb, ll_hlen);
skb_reset_network_header(skb);
nwp = (struct monitoring_hdr *)skb_put(skb, hdr_len);
/* ... Set up fields in struct monitoring_hdr ... */
memcpy(skb_put(skb, dev->addr_len), src, dev->addr_len);
memcpy(skb_put(skb, dev->addr_len), dst, dev->addr_len);
...
Receiver side:
...
skb_reset_network_header(skb);
nwp = (struct monitoring_hdr *)skb_network_header(skb);
src = skb_pull(skb, nwp->haddr_len);
dst = skb_pull(skb, nwp->haddr_len);
...
Expected output:
I used tcpdump to capture the packet in question on the wire, and saw this (it was actually padded to 60 bytes by the sender's NIC, which I've omitted):
0000 | 00 90 f5 c6 44 5b 00 0e c6 89 04 2f c0 df 01 03
0010 | 00 06 d0 ba 8c 88 00 0e c6 89 04 2f 00 90 f5 c6
0020 | 44 5b
The first 14 bytes is the Ethernet header. The following 8 bytes (starting with 01 and ending with 88) should be the bytes put into the struct monitoring_hdr, which executes correctly. Then, I am expecting the following MAC addresses to be found:
src = 00 0e c6 89 04 2f
dst = 00 90 f5 c6 44 5b
Actual output:
However, the data that I receive is shifted two bytes to the left:
src = 8c 88 00 0e c6 89
dst = 04 2f 00 90 f5 c6
Can anyone see a logical flaw in above code? Or is there a better way to do this? I've also tried skb_pull in place of skb_network_header on the receiving side, but that resulted in a kernel panic.
Thanks in advance for any help.
SOLUTION:
The pointer to the first byte of the data in the sk_buff was not being pointed to by src as it should have been. I ended up using the following:
...
skb_reset_network_header(skb);
nwp = (struct monitoring_hdr *)skb_network_header(skb);
skb_pull(skb, offsetof(struct monitoring_hdr, haddrs_begin));
src = skb->data;
dst = skb_pull(skb, nwp->haddr_len);
...
Looking at the skbuff.h header, the functions you are using look like this:
static inline void skb_reset_network_header(struct sk_buff *skb)
{
skb->network_header = skb->data - skb->head;
}
static inline unsigned char *skb_network_header(const struct sk_buff *skb)
{
return skb->head + skb->network_header;
}
extern unsigned char *skb_pull(struct sk_buff *skb, unsigned int len);
static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
{
skb->len -= len;
BUG_ON(skb->len < skb->data_len);
return skb->data += len;
}
So first, I would try printing out skb->data and skb->head to make sure they are referencing the parts of the packet you expect them to. Since you are using a custom protocol here, perhaps there is a bug in the header processing code which is causing skb->data to be set incorrectly.
Also, looking at the definitions of sky_network_header and skb_pull makes me think perhaps you are using them incorrectly. Shouldn't the first 6-byte addr be at the location pointed to be the return value of skb_network_header()? It looks like that function adds the length of the header block to the head of the buffer, which should result in a pointer to your first data value.
Similarly, it looks like skb_pull() adds the length of the field you pass in and returns the pointer to the next byte. So you probably want something more like this:
src = skb_network_header(skb);
dst = skb_pull(skb, nwp->haddr_len);
I hope that helps. I'm sorry that this is not an exact answer.
Trying to build Xuggler under Windows. Xuggler is core native code functions wrapped into Java for sound processing purposes (including ffmpeg).
My Windows is x64 Win 7 prof, but all used libraries are 32bit. I am running build procedure under MinGW/MSys, from under Msys shell with the followinf script:
#!/bin/sh
export JAVA_HOME=/C/Program\ Files\ \(x86\)/Java/jdk1.6.0_25
export XUGGLE_HOME=/C/Xuggler
PATH=$XUGGLE_HOME/bin:/C/Program\ Files\ \(x86\)/Java/jdk1.6.0_25/bin:/d/APPS/msysgit/msysgit/bin/git:/D/APPS/MinGW/bin:/bin:/D/APPS/apa che-ant-1.8.2/bin:/D/Users/Dims/Design/MinGW/Util:$PATH
ant -Dbuild.m64=no run-tests
Ant target contains some tests at the end, which give an error. The error follows
[exec] Running 6 tests..
[exec] In StdioURLProtocolHandlerTest::testRead:
[exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:108: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
[exec] In StdioURLProtocolHandlerTest::testReadWrite:
[exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:185: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
[exec] In StdioURLProtocolHandlerTest::testSeek:
[exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:139: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
[exec] .
[exec] Failed 3 of 6 tests
[exec] Success rate: 50%
[exec] FAIL: xugglerioTestStdioURLProtocolHandler.exe
UPDATE 1
The test code is follows:
int32_t totalBytes = 0;
do {
unsigned char buf[2048];
retval = handler->url_read(buf, (int)sizeof(buf));
if (retval > 0)
totalBytes+= retval;
} while (retval > 0);
VS_TUT_ENSURE_EQUALS("", 4546420, totalBytes);
While the url_read code is follows:
int
StdioURLProtocolHandler :: url_read(unsigned char* buf, int size)
{
if (!mFile)
return -1;
return (int) fread(buf, 1, size, mFile);
}
I don't understand, under what circumstances it can return 1042??? May be 64 bits play here somehow?
UPDATE 2
I printed out filename used and it was
d:/......./../../../test/fixtures/testfile.flv
the path is correct, but started with d:/ not with /d/
Can this play a role under Msys?
UPDATE 3
I have compared the readen bytes with real content of the test file and found, that fread() skips some bytes for some reason. Don't know which bytes yet, probably these are CR/LF
UPDATE 4
Not related with CR/LF I guess.
Original bytes are
46 4C 56 01 05 00 00 00 09 00 00 00 00 12 00 00 F4 00 00 00 00 00 00 00 02 00 0A 6F 6E 4D 65 74 61 44 61 74 61 08 00 00 ...
readen bytes are
46 4C 56 15 00 09 00 00 12 00 F4 00 00 00 02 0A 6F 6E 4D 65 74 61 44 61 74 61 80 00 B0 86 47 57 26 17 46 96 F6 E0 40 62 ...
This is FLV file begin. I don't understand the ptinciple of corruption.
How can 01 05 00 00 transform to just 15???
UPDATE 5
File opening done like following
void
StdioURLProtocolHandlerTest :: testRead()
{
StdioURLProtocolManager::registerProtocol("test");
URLProtocolHandler* handler = StdioURLProtocolManager::findHandler("test:foo", 0,0);
VS_TUT_ENSURE("", handler);
int retval = 0;
retval = handler->url_open(mSampleFile, URLProtocolHandler::URL_RDONLY_MODE);
VS_TUT_ENSURE("", retval >= 0);
int32_t totalBytes = 0;
printf("Bytes:\n");
do {
//...
url_open() function follows:
int StdioURLProtocolHandler :: url_open(const char *url, int flags)
{
if (!url || !*url)
return -1;
reset();
const char * mode;
switch(flags) {
case URLProtocolHandler::URL_RDONLY_MODE:
mode="r";
break;
case URLProtocolHandler::URL_WRONLY_MODE:
mode="w";
break;
case URLProtocolHandler::URL_RDWR_MODE:
mode="r+";
break;
default:
return -1;
}
// The URL MAY contain a protocol string. Find it now.
char proto[256];
const char* protocol = URLProtocolManager::parseProtocol(proto, sizeof(proto), url);
if (protocol)
{
size_t protoLen = strlen(protocol);
// skip past it
url = url + protoLen;
if (*url == ':' || *url == ',')
++url;
}
// fprintf(stderr, "protocol: %s; url: %s; mode: %s\n", protocol, url, mode);
mFile = fopen(url, mode);
if (!mFile)
return -1;
return 0;
}
Should be fixed in the GIT repository on the cross_compile branch as of today. I will roll this into tip of tree later this week / early next week.
Now the stdio handler opens all files as binary.