Make a file read-only?

Hi, I can make a file writeable easy enough,

mode = File.stat(file).mode
File.chmod(mode | 0000200, file)

But how do I make a file read-only?

mode = File.stat(file).mode
File.chmod(mode - 0000222, file)

Subtraction doesn’t work. And I’ve tried &, | and ^. Do I have to
do
some sort compliments operation here? What’s the trick to this?

FYI, on the command line it’s as easy as:

$ chmod a-w file

On 02/06/2012 01:38 PM, Intransition wrote:

Subtraction doesn’t work. And I’ve tried &, | and ^. Do I have to
do some sort compliments operation here? What’s the trick to this?

FYI, on the command line it’s as easy as:

$ chmod a-w file

More specifically, then, you want to remove the write permission from
the file, leaving it whatever other permissions were already set
(possibly none!). In other words, you want to /mask out/ the write bits
from whatever the current file mode is. Try the following:

mode = 0100664
mask = mode ^ 0222
new_mode = mode & mask

-Jeremy

Thanks. Seems almost obvious now that I see it.

On Monday, February 6, 2012 3:34:07 PM UTC-5, Jos B. wrote:

Nice! Almost worth kicking 1.8 totally to the curb for! :slight_smile:

On Mon, Feb 6, 2012 at 11:38 AM, Intransition [email protected]
wrote:

$ chmod a-w file

Ruby 1.9.3:

FileUtils.chmod ‘a-w’, ‘file’

On 02/07/2012 04:20 PM, Robert K. wrote:

Interesting approach. I usually do it like this:

irb(main):038:0> mode = 0100664
=> 33204
irb(main):039:0> mask = 0222
=> 146
irb(main):040:0> new_mode = (mode | mask) ^ mask
=> 33060
irb(main):041:0> “%07o” % new_mode
=> “0100444”

As far as I can tell, these approaches are functionally equivalent in
both result and efficiency. Folding the method I used all together
using your settings for mode and mask makes mine as follows:

new_mode = mode & (mode ^ mask)

I suspect that someone who more recently completed their college
philosophy of logic class than I might even remember how to derive one
of our solutions from the other using tidy boolean algebra. I’m too
rusty for it at the moment unfortunately, but I did give it a try. :frowning:

Maybe I’ll pick at it more tomorrow…

-Jeremy

On Mon, Feb 6, 2012 at 9:14 PM, Jeremy B. [email protected] wrote:

On 02/06/2012 01:38 PM, Intransition wrote:
More specifically, then, you want to remove the write permission from
the file, leaving it whatever other permissions were already set
(possibly none!). In other words, you want to /mask out/ the write bits
from whatever the current file mode is. Try the following:

mode = 0100664
mask = mode ^ 0222
new_mode = mode & mask

Interesting approach. I usually do it like this:

irb(main):038:0> mode = 0100664
=> 33204
irb(main):039:0> mask = 0222
=> 146
irb(main):040:0> new_mode = (mode | mask) ^ mask
=> 33060
irb(main):041:0> “%07o” % new_mode
=> “0100444”

Kind regards

robert

On Wed, Feb 8, 2012 at 7:46 AM, Jeremy B. [email protected] wrote:

new_mode = mode & mask
=> “0100444”

As far as I can tell, these approaches are functionally equivalent in
both result and efficiency.

Yeah, for all practical purposes I believe this is absolutely correct.
In a compiled language like C there might be a difference though
since my version uses two times the same constant and only one input
variable while your folded version below uses the input twice. But
that is certainly microoptimization one should only do when
implementing a gigabit router or something with similar need for
speed. :slight_smile:

Maybe I’ll pick at it more tomorrow…
:slight_smile:

Kind regards

robert