Pass more than filename argument to stat()? - linux

I'd like to know if it's possible (no matter why) to pass more than just a filename for existing file to stat() function, so it would not fail and return 0?
I mean like this:
struct stat mystat; char file[100];
...
if(stat(file, &mystat)==0){
//success
}
Is it possible to specify file as "existing-file_some_special_chars_maybe_some-text" and to stat() not fail on that?

stat() works on filenames, so if you're passing in something that isn't a filename, you shouldn't be surprised that it fails. You can use fstat() to get information on whatever file a file handle is pointing to, but otherwise you're stuck with just filenames.

How about just creating a list of file names and feeding them to stat() one by one?

Related

invalid syntax with shutil library

I want to try using this shutil.copy and my files got some symbolic characters inside its name, so I need to use this shutil.copy(src, dst, *, follow_symlinks=True) command. but the compiler keeps giving me the invalid syntax messages. I had google and didn't find any solution yet for this. anyone can point out what is wrong with my syntax? because I already tried to print out the files inside those directories and it is okay, the network shared folder also got the permission and so on. but don't know what is wrong with my syntax. help me. thanks
This is my current script
and here is the output I got
File "C:\Users\1000266946\Desktop\sa\we.py", line 17
shutil.copy( files, parse_destination_path, * , follow_symlinks = True)
^
SyntaxError: invalid syntax
[Finished in 0.3s]
first of all: the asterisk as you show it can be used in function definitions to define keyword-only arguments (see e.g. here) - but you don't use it in a function call. So in shutil.copy(src, dst, *, follow_symlinks=True) in the docs, it tells you that follow_symlinks can only be used as a keyword argument, not as a positional argument.
second: take a look at the return value of os.listdir(). it returns only file names, without the path as noted in the docs. shutil.copy() however expects a full path, not only the filename. so what you could do is
for file in parse_source_file_list:
shutil.copy(os.path.join(parse_source_path, file), os.path.join(parse_destination_path, file))
further reading: you might also be interested in having a look at glob and pathlib for file handling purposes (docs here and here).

How to read contents of a directory recursively in Linux Kernel?

I want to implement a tree traversal function which prints all the contents of a given directory
in kernel . I know how to do this in user space, but my requirement is to have that in kernel space.
For that, I am looking into vfs_readdir function and a bit confused regarding its usage.
Say I will be calling my traversal function from other kernel module which means that request won’t be coming through user space. Now the question is how to call vfs_readdir and use that information to recursively parse given directory. From definition of vfs_readdir
extern int vfs_readdir(struct file *, filldir_t, void *);
I can get struct file * from the file path using functions like filp_open() and as per my understanding filldir_t is a function pointer to call back function which fills the user provided buffer pointed by void *. But in my case, I don’t need to pass any information to user back. What should i pass in void * place?
Looking into filldir function definition
static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned int d_type);
From where are the parameters to this function are coming. My assumption is that vfs_readdir in turn calls something like file->f_op_readdir(file,but,filler);
Does this internally does something and fills in parameters to call callback function ?
Now this is one level. What should I do to recursively print all files in a given directory. I guess I need to do something in my own callback function.But I have only some information regarding the file that are passed through this call back functions like name of file,inode number etc . How would I know if it is regular file or directory using this information . I mean I don't have dentry or inode data structures regarding the file. Any suggestions how to do that?
In addition, If I want to delete a file in callback function, can I do that by using inode numbers(thats what i have in callback apart from names) how should I do that?
vfs_readdir is called, e.g., from readdir syscall implementation. It uses fillonedir as callback, which in turn can easy be understanded: its first argument is just last argument of vfs_readdir, all other arguments(name, namelen, offset, ino, d_type) are copied into user space as is.
Note, that callback for vfs_readdir is executed with inode mutex locked(inode->i_mutex). Probably you shoudn't open subdirectory incide that callback. Instead, save name of the subdirectory somewhere, and open it after vfs_readdir call. This is very similar to the way how you traverse directories tree in the user space.
Note, that since version 3.11 kernel uses another way for iterate entries in directory: iterate_dir. Its second argument combines both callback and callback-specific argument for it, and also include current position in the file. Aside from the first parameter, callback accepts same parameters as before.
As for ino argument, you cannot use it for open given inode(kernel just has no mechanism for open files by inode number). Use filp_open or similar.

Trick open() into reading from a non-file?

I realize this is a pretty weird thing to want to do - it's mainly just to simplify my unittests.
I have a class whose __init__ takes a filename as an argument, which it open()s and reads a bunch of data from. It'd be really awesome if I could somehow "trick" that open() into reading from a string object instead without actually writing a temporary file to disk.
Is this possible, and if so, how would I go about it?
You can monkey-patch the module that contains the class before running the test, and restore it after the test:
def my_fake_open(fake_filename):
return object_with_read_and_close_that_will_feed_correct_data()
def test_something(self):
module_containing_test.open = my_fake_open
...run test...
del module_containing_test.open
Check out the mock library if you don't want to write your own mock objects.
Reading a bit too fast, I thought the answer would be in io.stringIO which allows you to create a file-like object with the content of a string.
But what you want, is an object that, passed to the standard open function would actually yield a file-like object from the contents of the your string.
The thing is that open takes a string (or a file descriptor) but anything else will pause a problem.
So I don't believe this way is practical.
But actually, it's not difficult to create a file using tempfile:
with tempfile.NamedTemporaryFile() as tmp_file:
tmp_file.write(your_string)
yourmodule.YourClass(tmp_file.name)
(If you're on Windows you might want to play with delete=False and close before sending the name for it to be opened.)
Another approach might be to just change the API: if all the init does with the name is to open a file, why not directly pass a file-like object.

Is there a c-runtime function equivalent of fscanf, which contains the same parameter list?

Hi i have a function like this
while(fscanf(fp,"\n%d\t%s\t%s\t%X%X\t%d\t \n",&record.Index,record.Name,record.Empcode,&record.CSN_MSB,&record.AccessRights)!=EOF)
{
printf("\nIndex: %d\nEmployee Name: %s\nEmpcode: %s\nCSN: %X\nAccessRights: %d\n",record.Index,record.Name,record.Empcode,record.CSN_MSB,record.AccessRights);
sprintf(CSN_MSB_LSB,"%X", record.CSN_MSB);
if(strncmp(CSN_MSB_LSB,str,8)==0)
found=1;
}
in this code my fscanf is reading only one line from file pointer fd, i want to read all the lines from the file.
how i can i do this
with same fscanf function or else any alternative which contains the same parameter list for the fscanf function please suggest me
I would try something of the sort:
while(fscanf(fp,"%d%s%s%X%X%[^\n]*c",
&record.Index,record.Name,record.Empcode,
&record.CSN_MSB,&record.AccessRights)!=EOF)
{
Though, it is worth noting that you are scanning 6 items and only storing 5. Also, you are using sscanf which takes a pointer to a character and passing it a file pointer (file descriptor), you want to use fscanf if reading from a file. The last number you scan never gets stored. The "[^\n]" says scan until a newline and takes place of the last number you are scanning for (though you don't save it in your example) and the "*c" consumes that newline. See this.

Returning Filename with wildcards in VFP 9

I am trying to locate the full name of a file using a wildcard. The code I have is:
MLCNo=crjbis.ffromlot
subfolder=LEFT(mlcno,3)
filename=SYS(2000,'S:\MLC\MLC#\'+subfolder+'xx\'+mlcno+'21391*.pdf')
pathname="S:\MLC\MLC#\"+subfolder+"xx\"+filename
Pathname is passed to a print function to print the file. All of this works great if I don't use a variable in the SYS function (even with a wildcard). I should add that there will only ever be one file returned by the wildcard. Is there another way to do this?
Thanks!!!
Tammy

Resources