Matt56867 |
01-05-2012 06:04 AM |
Quote:
I would suggest adding -Wall -Wextra, fix any resulting warnings
|
Thanks for that tip, I got Loads of warnings...
Code:
New Warning list:
toppyfsusb.c: In function 'toppy_opendir':
toppyfsusb.c:165: warning: embedded '\0' in format
toppyfsusb.c:211: warning: spurious trailing '%' in format
toppyfsusb.c:211: warning: embedded '\0' in format
toppyfsusb.c:232: warning: pointer targets in passing argument 2 of 'strcpy' differ in signedness
toppyfsusb.c:190: warning: unused variable 'return_count'
toppyfsusb.c: In function 'toppy_open':
toppyfsusb.c:442: warning: format '%d' expects type 'int', but argument 3 has type 'uint64_t'
toppyfsusb.c:449: warning: format '%d' expects type 'int', but argument 3 has type 'uint64_t'
toppyfsusb.c: In function 'toppy_read':
toppyfsusb.c:568: warning: format '%d' expects type 'int', but argument 3 has type 'off_t'
toppyfsusb.c:568: warning: format '%d' expects type 'int', but argument 4 has type 'off_t'
toppyfsusb.c:597: warning: format '%d' expects type 'int', but argument 4 has type 'off_t'
toppyfsusb.c:637: warning: format '%d' expects type 'int', but argument 3 has type 'off_t'
toppyfsusb.c:637: warning: format '%d' expects type 'int', but argument 4 has type 'off_t'
toppyfsusb.c: In function 'toppy_flush':
toppyfsusb.c:681: warning: unused parameter 'fi'
toppyfsusb.c: At top level:
toppyfsusb.c:709: warning: initialization from incompatible pointer type
toppyfsusb.c: In function 'main':
toppyfsusb.c:748: warning: implicit declaration of function 'open_the_usb'
toppyfsusb.c:757: warning: spurious trailing '%' in format
toppyfsusb.c:757: warning: embedded '\0' in format
toppyfsusb.c: In function 'open_the_usb':
toppyfsusb.c:778: warning: unused variable 'HndOther'
toppyfsusb.c:777: warning: unused variable 'i'
toppyfsusb.c: At top level:
toppyfsusb.c:104: warning: 'out_buffer' defined but not used
toppyfsusb.c:682: warning: 'toppy_flush' defined but not used
usb_io.c: In function 'get_crc':
usb_io.c:164: warning: unused parameter 'packet'
usb_io.c:418:9: warning: "/*" within comment
I've trimmed it down to:
Code:
toppyfsusb.c: In function 'toppy_opendir':
toppyfsusb.c:316: warning: pointer targets in passing argument 2 of 'strcpy' differ in signedness
toppyfsusb.c: At top level:
toppyfsusb.c:794: warning: initialization from incompatible pointer type // It appears to work correctly
toppyfsusb.c:104: warning: 'out_buffer' defined but not used // Have not used this yet
But I dont know if:
"toppyfsusb.c:316: warning: pointer targets in passing argument 2 of 'strcpy' differ in signedness"
is a problem?
"strcpy(dir_contents[dir_contents_count].tf_name , entries[i].name);"
... strcpy ... char tf_name[95] ... from ... __u8 name[95]
I have added more code this time, I have not added all of it, because I think it would be a waist of time.
Code:
>> Top Level usb_io.h:
struct typefile
{
struct tf_datetime stamp;
__u8 filetype;
__u64 size;
__u8 name[95];
__u8 unused;
__u32 attrib;
} __attribute__ ((packed));
>> Top Level toppyfsusb2.c:
#include <sys/stat.h> // for the normal stat struct
#define max_path_len 500 // maybe 4096, but thats too much
struct typefile *entries; // dir & file entries from usb packet
static char path_in_memory[max_path_len]; // The dir currently in 'entries' memory
static int dir_contents_count;
typedef struct
{
time_t tf_mtime; // time of last modification
char tf_type; // file or folder
off_t tf_size; // total size, in bytes
char tf_name[95]; // name
// spare 4 bytes RFU
} stat_small;
static stat_small dir_contents[580]; // nearly 64K
static const char *recordings_dir = "/Recordings";
Lower Down:
// This is the complete function...
static int toppy_opendir(const char *path, struct fuse_file_info *fi)
{
(void) fi; // ignored, because its read-only stuff this is doing
int i;
printf("toppy_opendir=%s\n",path);
// Load it in...
strcpy(path_in_memory,path);
// Copy and adjust path slashes
static char path_slash[max_path_len];
strcpy(path_slash,path);
for(i = 0; i < max_path_len; ++i)
{
if (path_slash[i] == '/')
{
path_slash[i] = '\\';
}
}
dir_contents_count = 0;
// Check for Recordings Directory and Fake it
if (strcmp(path, recordings_dir) == 0)
{
sprintf(path_slash, "\\DataFiles");
}
// If its the root Dir, add the fake Directory
if (strcmp(path, "/") == 0)
{
dir_contents[dir_contents_count].tf_mtime = 1325376000; // 01 Jan 2012
dir_contents[dir_contents_count].tf_type = 4; // Directory - S_IFDIR * 1000
dir_contents[dir_contents_count].tf_size = 0;
strcpy(dir_contents[dir_contents_count].tf_name , recordings_dir + 1);
dir_contents_count = 1;
}
//open_the_usb();
int ret = 0;
int count = 0;
int try_count = 0;
try_cmd_again:;
// Send the get directory command
i = send_cmd_hdd_dir(HndUsb, path_slash);
printf("send_cmd_hdd_dir i=%d new_path=%s\n", i, path_slash);
while(0 < (ret = get_tf_packet(HndUsb, &reply)))
{
// Check for a 'Fail' return
// This occurs when 2 quick consecutive directory reads happen, adding a short pause does not help
if (reply.cmd == 1)
{
printf("ERROR: cmd_fail - code %s\n", decode_error(&reply));
try_count = try_count + 1;
if (try_count <= 2)
{
goto try_cmd_again;
}
sprintf(path_in_memory,"?*#"); // Set a dummy path
//toppy_destroy();
return -EREMOTEIO; // Remote I/O error
}
count = count + (get_u16(&reply.length) - PACKET_HEAD_SIZE) / sizeof(struct typefile);
entries = (struct typefile *) &reply.data;
for(i = 0; (i < count); i++)
{
//printf("entry%d=%s\n",i,entries[i].name);
// Save the info into the stat_small struct
dir_contents[dir_contents_count].tf_mtime = tfdt_to_time(&entries[i].stamp);
if (entries[i].filetype == 1)
{ // Directory - S_IFDIR * 1000
dir_contents[dir_contents_count].tf_type = 4;
}
else
{ // File - S_IFREG * 1000 (or other)
dir_contents[dir_contents_count].tf_type = 8;
}
dir_contents[dir_contents_count].tf_size = get_u64(&entries[i].size);
strcpy(dir_contents[dir_contents_count].tf_name , entries[i].name);
dir_contents_count=dir_contents_count + 1;
} // for
if (dir_contents_count >= count) { break; } // probably fail-ish, if >1 packet
} // while
if (dir_contents_count > 580) { printf("WARNING: Directory count > 580, possible memory corruption\n"); }
//toppy_destroy();
return 0;
}
// This func is called by the kernel driver ( I guess... in some way ? )
// This is the complete function...
static int toppy_getattr(const char *path, struct stat *stbuf) // this 'path' contains the full path and file name
{
int i;
char path_n_file[strlen(path)+10]; // +X any number >1, for string compare
char just_the_path[strlen(path)];
printf("toppy_getattr=%s, memory_dir=%s\n", path, path_in_memory);
memset(stbuf, 0, sizeof(struct stat));
// Allow the root
if (strcmp(path, "/") == 0)
{
stbuf->st_mode = S_IFDIR | 0744;
stbuf->st_nlink = 2; // Number of hard links ?
return 0;
}
// Allow the current directory - helps stop a directory rescan
else if (strcmp(path, path_in_memory) == 0)
{
stbuf->st_mode = S_IFDIR | 0744;
stbuf->st_nlink = 2;
return 0;
}
// Quick exit with close
if(strcmp(path,"/cmd_exit")==0)
{
printf("bye bye\n");
toppy_destroy();
exit(0);
//fuse_exit(0);
//fuse_session_destroy(0);
//return 0;
}
else if(strcmp(path,"/cmd_cancel")==0)
{
printf("sending cancel...\n");
send_cancel(HndUsb);
}
else if(strcmp(path,"/cmd_success")==0)
{
printf("sending success...\n");
send_success(HndUsb);
}
// Get just the path from the path string
strcpy(just_the_path,path);
for(i = strlen(path); i > 0; i = i - 1)
{
if (just_the_path[i] == '/')
{
just_the_path[i] = '\0';
break;
}
}
// A check so see if its the root
if (i == 0) { just_the_path[1] = '\0'; }
printf("just_the_path=%s (%d)\n", just_the_path, i);
// Check if it is in memory first
if (strcmp(just_the_path, path_in_memory) != 0)
{
printf("Not Match - rescan\n");
i = toppy_opendir(just_the_path, NULL);
if (i != 0) { return i; } // I/O Error check
// Quick check its the main directory
if (strcmp(path, path_in_memory) == 0)
{
stbuf->st_mode = S_IFDIR | 0744;
stbuf->st_nlink = 2;
return 0;
}
}
// Loop though all the entries
for(i = 0; (i < dir_contents_count); i++)
{
// Look for a ending slash
if (strlen(path_in_memory) == 1 )
{
sprintf(path_n_file,"/%s",dir_contents[i].tf_name);
}
else
{
sprintf(path_n_file,"%s/%s",path_in_memory,dir_contents[i].tf_name);
}
if (strcmp(path_n_file, path) == 0)
{
printf("prt=%#Xp (%d)\n", stbuf , i);
// Warning, when 'ls xxx/DataFiles -l' might cause a 'Segmentation Fault' when not optimised -O2
stbuf->st_mtime = dir_contents[i].tf_mtime;
stbuf->st_ctime = dir_contents[i].tf_mtime;
stbuf->st_size = dir_contents[i].tf_size;
stbuf->st_mode = (dir_contents[i].tf_type * 0x1000) | 0744;
stbuf->st_nlink = 1;
printf("exit from=%d\n", i);
return 0;
}
}
printf("exit from=%d\n", i);
return -ENOENT; // No such file or directory
}
static struct fuse_operations toppy_oper = {
.destroy = toppy_destroy, // Line 794
.opendir = toppy_opendir,
.readdir = toppy_readdir,
.getattr = toppy_getattr,
.open = toppy_open,
.read = toppy_read
// .flush = toppy_flush
};
I dont think there are any memory overflows? (But I am just a beginner)
I have allocated plenty of memory place for each variable, and they 'should' not overrun...
Code:
The only thing I can think of that would cause segfault is that stbuf->st_mtime points outside your address space
? I dont know, stbuf appears to go back into the FUSE system, and I dont know what happens from there, sorry ?
Quote:
You can print the value of a pointer in hex by specifying %#Xp as the print specifier
|
Thanks for that.. I can now see that it appears to use the same pointer (prt=0XBEBC7AA8p), but uses (prt=0X656300A8p) when it crashes, when it is not optimised.
When -O2 is used it still uses a high pointer value 0xBEE32AB8 (And all the same for each entry) and works :)
But... when -O1 is used, it still uses a high pointer value 0xBE9FBAB8 for each entry, but caused a seg fault as well ?
The Segmentation fault appears to happen after my function has exited.
ay ay ayy, this is a good learning experience for me.
Cheers guys,
Matt
|