In the plan9 specific Go code for syscall, there is no Stat_t like with other GOOS. Where is Stat_t, or its equivalent defined?
TL;DR: It's the *syscall.Dir type. Read on for details.
The source for os.Stat on Plan9 is here. It calls dirstat, which is defined here. It feeds the return value of dirstat into fileInfoFromStat, which is defined in the same file here.
In the case of paths (as opposed to *File objects), dirstat just calls syscall.Stat, which is basically just a thin wrapper around stat. syscall.Stat expects a byte buffer to be able to write into. This buffer is processed a bit (see dirstat for details), and then fed into syscall.UnmarshalDir, which is where the magic happens. The documentation states that it "decodes a single 9P stat message" from a buffer and returns a *syscall.Dir.
dirstat then passes this *syscall.Dir to fileInfoFromStat, which is what processes it into a FileInfo. It's this *syscall.Dir value that is obtained through the Sys() method on the FileInfo object.
Related
I'm currently trying to learn GO and mainly knowing and working with Java, ASP.Net and some Python, there is no experience working with C-like pointers, which causes my current confusion.
A library I'm currently using to write my first GO project is called Commando.
There I have the struct CommandRegistry and the variable of interest is called Commands.
In the struct the variable is described as the following:
// registered command configurations
Commands map[string]*Command
On a first glimpse I would understand this as a Map object containing a list of Strings, however it also shows the pointer reference to the actual Command object.
All I can see is that it is a map I can loop over which returns the name of the command ( the string ),
however I'm wondering if the *Command in the type description means I can somehow dereference the pointer and retrieve the object itself to extract the additional information of it.
As I know the & operand is used to create a new pointer of another object. Pass-by-reference basically instead of pass-by-value.
And the * operand generally signals the object is a pointer or used to require a pointer in a new function.
Is there a way I can retrieve the Command object or why does the type contain the *Command in it's declaration?
Commands is a map (dictionary) which has strings as keys, and pointers to Commands as values. By passing it a key, you will get a pointer to the command it belongs to. You can then dereference the pointer to an actual Command object by using the * operator. Something like dereferencedCommand := *Commands["key"].
The * operator can be quite confusing, at least it was for me. When used as a type it denotes that we are receiving the memory address of some variable. But to dereference a memory address to a concrete type, you also use the * operator.
When using the OpenFile function in Go's os package, what exactly is the purpose of the pipe character?
Example:
os.OpenFile("foo.txt", os.O_RDWR|os.O_APPEND, 0660)
Does it serve as a logical OR? If so, does Go choose the first one that is "truthy"?? Being that the constants those flags represent, at the heart of them are just integers written in hexadecimal, when compiled how does Go choose which flag to apply?
After all, if the function call were to go by the largest number, os.O_APPEND would take precedence over all other flags passed in as seen below:
os.O_RDWR == syscall.O_RDWR == 0x2 == 2
os.O_APPEND == syscall.O_APPEND == 0x400 == 1024
os.O_CREATE == syscall.O_CREAT == 0x40 == 64
UPDATE 1
To follow up on the comment below, if I have a bitwise operator calculation using os.O_APPEND|os.O_CREATE will that error if the file exists, or simply create/append as needed?
UPDATE 2
My question is two fold, one to understand the purpose of the bitwise operator, which I understand now is being used more as a bitmask operation; and two, how to use the os.OpenFile() function as a create or append operation. In my playing around I have found the following combination to work best:
file, _ := os.OpenFile("foo.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0660)
file.WriteString("Hello World\n")
file.Sync()
Is this the correct way or is there a more succinct way to do this?
It is a bitwise, not a logical OR.
If you write out the numbers in binary, and assign each a truth value 0/1, and apply the logical OR to each of the bits in place i between the arguments, and then reassemble the result into an integer by binary expansion - that's the | operator.
It is often used in a way that is commonly described as a "bitmask" - you use a bitmask when you want a single int value to represent a (small) set of switches that could be turned on or off. One bit per switch.
You should see in this context, A | B means "all the switches in A that are on, as well as all the switches in B that are on". In your case, the switches define the exact behavior of the file open/creation function, as described by the Go manual. (And probably more in detail by the Unix manpage I linked above).
In a bitmask, constants are typically defined that represent each switch - that's how those O_* constants are determined. Each is an int with exactly one bit set and represents a particular switch. (though, be careful, because sometimes they represent combinations of switches!).
Also:
^A // All of the "switches" not currently on in A
A&^B // All of the "switches" on in A but not on in B
A^B // All of the "switches" on in exactly one of A or B
, etc.
The operator | itself is described in the Go manual here.
It is a bitwise OR operator. Its purpose being used here is to allow for multiple values to be passed as a bitmask. Thus you can combine flags to create a desired result such as using the OpenFile() function to create a file if it does not exist or append to it if it does.
os.Openfile("foo.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0660
The constants being passed as arguments from the os package are assigned values from the syscall package. This package contains low-level operating system independent values.
Package syscall contains an interface to the low-level operating system primitives. The details vary depending on the underlying system, and by default, godoc will display the syscall documentation for the current system. If you want godoc to display syscall documentation for another system, set $GOOS and $GOARCH to the desired system. For example, if you want to view documentation for freebsd/arm on linux/amd64, set $GOOS to freebsd and $GOARCH to arm. The primary use of syscall is inside other packages that provide a more portable interface to the system, such as "os", "time" and "net".
https://golang.org/pkg/syscall/
As noted by #BadZen, a bitwise OR operator, in this case the '|' character, acts at the binary level changing any 0 values to 1's that are not already ones.
You should see in this context, A | B means "all the switches in A that are on, as well as all the switches in B that are on".
By doing this as the function above displays, you are manipulating the behavior of the function to create a file (os.O_CREATE) with the given name of foo.txtor open the file for reading/writing (os.O_RDWR) and any value written to it will be appended (os.O_APPEND). Alternatively you could pass along os.O_TRUNC in order to truncate the file before writing.
The bitwise OR operator allows you a powerful solution to combining different behaviors in order to get the result from the function that you are desiring.
If we open some arbitrary file using fopen() we get a pointer to it and it seems on windows, it will be stored in varying address (for example 1fb8e50)
So can I declare a second pointer to it, from another instance like that:
volatile FILE* fp = (volatile FILE*)0x1fb8e50;
And use them both. Is that dangerous or just possible for that matter?
According to the statements made in the answers of these questions
Is writing to &str[0] buffer (of a std:string) well-defined behaviour in C++11?
Is it legal to write to std::string?
writing directly to std::string internal buffers
.. in C++11 it should be possible to call a C API function which takes a char pointer to store the output like this:
str::string str;
str.reserve(SOME_MAX_VALUE);
some_C_API_func(&str[0]);
But is there now a legal way to set the size of the string to the length of the (null terminated) content inside the buffer? Something like this:
str.set_size(strlen(&str[0]));
This is a very unaesthetic abuse of std::string anyway I hear you say, but I can't create a temporary char buffer on stack so I would have to create a buffer in heap and destroy it afterwards (which I want to avoid).
Is there a nice way to do this? Maybe not reserving but resizing and calling erase() afterwards would do it but it doesn't feel nice neater..
You should be using resize() not reserve(), then resize() again to set the final length.
Otherwise when you resize() from zero to the result returned by strlen() the array will be filled with zero characters, overwriting what you wrote into it. The string is allowed to do that, because it (correctly) assumes that everything from the current size to the current reserved capacity is uninitialized data that doesn't contain anything.
In order for the string to know that the characters are actually valid and their contents should be preserved, you need to use resize() initially, not reserve(). Then when you resize() again to make the string smaller it only truncates the unwanted end of the string and adds a null terminator, it won't overwrite what you wrote into it.
N.B. the initial resize() will zero-fill the string, which is not strictly necessary in your case because you're going to overwrite the portion you care about and then discard the rest anyway. If the strings are very long and profiling shows the zero-filling is a problem then you could do this instead:
std::unique_ptr<char[]> str(new char[SOME_MAX_VALUE]);
some_C_API_func(str.get());
This was/is a known limitation of C++ until C++20.
From C++23 you can use resize_and_overwrite():
I've been trying to understand the differences between the two, but as of now I have a very rudimentary understanding. ARGV is a subset of IO I believe. I know that ARGV returns an array when called into a Ruby script, but IO does the same thing as well. Can anyone explain this topic to me or direct me to a good explanation? I've searched multiple blogs but to no avail.
Thanks!
ARGV is an array:
> ARGV.class
=> Array
This array contains the command line arguments for your script. For example:
$ cat pancakes.rb
puts ARGV.inspect
$ ruby pancakes.rb -where is house
["-where", "is", "house"]
IO is quite a bit different. IO is:
[...] the basis for all input and output in Ruby. [...]
Many of the examples in this section use the File class, the only standard subclass of IO. The two classes are closely associated. Like the File class, the Socket library subclasses from IO (such as TCPSocket or UDPSocket).
IO is the base class for file-like things in Ruby.
Perhaps you're thinking of ARGF rather than ARGV:
ARGF is a stream designed for use in scripts that process files given as command-line arguments or passed in via STDIN.
The arguments passed to your script are stored in the ARGV Array, one argument per element. ARGF assumes that any arguments that aren't filenames have been removed from ARGV.
[...]
If ARGV is empty, ARGF acts as if it contained STDIN, i.e. the data piped to your script.
So you can use ARGF like an IO that lets you say:
$ your_script some_file
and
$ some_command | your_script
without your_script really having to care about which way it is called.
The IO class is the basis for all input and output in Ruby. An I/O stream may be duplexed (that is, bidirectional), and so may use more than one native operating system stream.
Many of the examples in this section use the File class, the only
standard subclass of IO. The two classes are closely associated. Like
the File class, the Socket library subclasses from IO (such as
TCPSocket or UDPSocket).
The Kernel#open method can create an IO (or File) object for these
types of arguments:
A plain string represents a filename suitable for the underlying
operating system. A string starting with "|" indicates a subprocess.
The remainder of the string following the "|" is invoked as a process
with appropriate input/output channels connected to it. A string equal
to "|-" will create another Ruby instance as a subprocess. The IO may
be opened with different file modes (read-only, write-only) and
encodings for proper conversion. See ::new for these options. See
Kernel#open for details of the various command formats described
above.
Source: http://www.ruby-doc.org/core-2.1.2/IO.html
ARGF is a stream designed for use in scripts that process files given as command-line arguments or
passed in via STDIN.
The arguments passed to your script are stored in the ARGV Array, one
argument per element. ARGF assumes that any arguments that aren't
filenames have been removed from ARGV.
argv → ARGV Returns the ARGV array, which contains the arguments
passed to your script, one per element.
Source: http://www.ruby-doc.org/core-2.1.2/ARGF.html