Category Archives: operating system

operating system

notes on and related to umask

<pre>
umask – set file mode creation mask

#include <sys/types.h>
#include <sys/stat.h>

mode_t umask(mode_t mask);

 

Binary Number ————–> Decimal Number
Abstraction

Decide the required result to decide the needed mask.

Binary Number ——————-> Resultant Binary
ANDing with mask
</pre>

Bit level Operations in C

Bit-Level Operations in C

Technical Overview

One of the reasons why C has become so popular is that it allows the programmer to do many types of machine-level applications without resorting to using machine language as the vehicle for programming. One example of that is C’s ability to work with memory addresses. Another example, or class of examples, consists of C constructs for bit-level operations, which will be described here.

AND and OR Operators

C includes the bitwise-AND operator & and the bitwise-OR operator |. To AND two bits together, one merely multiplies them: 0 AND 0 = 0, 1 AND 0 = 0, 0 AND 1 = 0, 1 AND 1 = 1. To OR two bits together, we just add them, except that 1 OR 1 is equal to 1, not 2: 0 OR 0 = 0, 1 OR 0 = 1, 0 or 1 = 1, 1 or 1 = 1.

Note that

AND-ing by a 1 simply copies the bit value
OR-ing by a 0 simply copies the bit value
AND-ing by a 0 results in a 0, not matter what the original bit value was
OR-ing by a 1 results in a 1, not matter what the original bit value was
The AND operator is useful for

(a)
putting 0s in certain bit positions of a variable, while retaining whatever original values were in the other bit positions
(b)
testing whether certain bit positions within a variable contain 1s or 0s
In the next few examples, suppose the variable X is of type int.

As an example of (a), suppose we wish to put 0s in Bit Positions 3 and 2 (the rightmost bit position being Bit Position 0), and suppose we have a machine/compiler combination which implements int variables as 4-byte quantities (again, this is typical for most workstations today). We would accomplish our goal with the statement

X &= 0xfffffff3;
Here is why: First, note that

X &= 0xfffffff3
is just a short form of

X = X & 0xfffffff3
(like X += 5 vs. X = X + 5). So we are AND-ing 0xfffffff3 with X and putting the result back in X. The constant 0xfffffff3 is, in bit form,

11111111111111111111111111110011
Most of the bits here are 1s, and since, as mentioned earlier, AND-ing by a 1 produces no change, most bits in X will not change. Only the bits at Bit Positions 3 and 2 will potentially change: They will change to 0s if they were 1s (or stay at 0s if they were 0s).

For example, after executing the statements

X = 29;
X &= 0xfffffff3;
X will have the value 17 (try this yourself on the machine, and make sure you understand).

By the way, the value to be AND-ed with X, in this case 0xfffffff3, is called a mask. To see why, think of what happens when you wish to paint the walls of a room. You would like to cover up the electrical sockets so that they don’t get painted; you can do this with masking tape. Well, in the example above, we wished to “cover up” all the bits except those at Bit Positions 3 and 2, so we AND-ed them with 1s, so that they would not change.

As an example of (b), suppose we wish to set Z = 12 if there is a 1 in Bit Position 5 of X. We could do this with the statement

if (X & 0x00000020) Z = 12;
Here is why this statement accomplishes this goal: The mask 0x00000020 has 0s everywhere except in Bit Position 5, where there is a 1. Recall from above that AND-ing with a 0 produces a 0, no matter what value it is AND-ed with, while AND-ing with a 1 results in copying the bit value. So the quantity X & 0x00000020 will have 0s everywhere except at Bit Position 5, where there will be a copy of X’s original Bit 5. If the latter is a 1, then X & 0x00000020 will be nonzero (0x00000010, to be specific), and since any nonzero value is condidered `true’, Z = 12 will be executed.

OR-ing is used to put 1s at specific bit positions. You should verify, and make sure you understand, that after the statements

X = 29;
X |= 0x00000020;
are executed, X will be equal to 61.

Shift Operators

The operators << and >> shift the bits in a variable toward the left or toward the right, respectively. Suppose for example that X and Y are of type int, and we execute

X = 5;
Y = X << 3;
Then (say on the CAE machines) X will be, in bit form,

00000000000000000000000000000101
All these bits will be shifted left by 3 positions, and the result placed in Y. The latter will now be

00000000000000000000000000101000
which has the value 40.

footnote: Note that since we are tacking three 0s on the right end, and we are working in base-2, we are in effect multiplying by . (In base-10, tacking on a 0 on the right does a multiplication by 10, e.g. 52 to 520, so in base-2, appending a 0 on the right does a multiplication by 2.) Thus since X was 5, Y will be 40.
Note that the bits on the left end disappear. This may create problems. For example, shifting may turn a positive number into a negative one, or vice versa, since the leftmost bit of a number tells its sign. This presents no problem, though, for variables of type unsigned, so shift operations are typically done on variables of that type, not of type int.

Bit Fields

These arise in a special type of struct, which allows one to assign variable names to groups of bits within a variable. We will not go into this here.

http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/BitOps.html

GNU coreutils: Sources of random data

script file contents

#!/bin/bash

get_seeded_random()
{
    seed="$1"
    echo $seed
    openssl enc -aes-256-ctr -pass pass:"$seed" -nosalt \
	    /dev/null
}

shuf -i1-100 --random-source=<(get_seeded_random 45)

using /dev/urandom

$sudo shuf -i1-5 --random-source=/dev/urandom
1
2
4
3
5
$sudo shuf -i1-5 --random-source=/dev/urandom
3
4
5
1
2
$sudo shuf -i1-5 --random-source=/dev/urandom
4
5
2
1
3
$sudo shuf -i1-5 --random-source=/dev/urandom
4
2
3
1
5
$sudo shuf  --random-source=/dev/urandom
^C
$sudo shuf -i1-10 --random-source=/dev/urandom
2
4
6
10
7
8
5
3
1
9
$sudo shuf -i1-10 --random-source=/dev/urandom
6
2
10
3
5
8
7
9
4
1
$sudo shuf -i1-10 
5
4
10
8
9
6
7
1
2
3
$sudo shuf 
qq


qq
$sudo shuf -i1-100 --random-source=/dev/urandom
65
51
62
79
41
35
26
36
52
77
54
82
48
99
75
17
39
31
1
7
88
61
9
94
73
70
63
55
44
38
23
84
15
25
53
85
66
16
20
69
81
32
98
45
96
49
74
10
4
59
93
40
12
13
50
100
14
90
6
68
8
57
5
34
60
67
80
3
2
78
18
76
21
92
33
56
24
37
87
83
47
29
97
46
89
43
91
27
11
58
64
19
28
86
95
72
30
22
71
42
$sudo shuf -i1-100 --random-source=/dev/random
8
79
40
19
62
27
90
71
9
93
32
85
21
3
26
31
63
18
99
2
78
11
100
49
75
64
37
13
39
30
29
73
82
34
55
14
35
80
84
33
67
98
92
25
87
51
41
88
10
4
97
45
53
68
16
15
47
46
42
36
54
94
70
28
61
83
58
96
69
91
59
1
72
38
5
23
60
12
74
44
7
52
48
86
43
95
20
65
50
24
76
22
6
66
81
89
56
77
17
57
$sudo shuf -i1-100 --random-source=/dev/null
shuf: ‘/dev/null’: end of file
$sudo shuf -i1-100 --random-source=/dev/zero
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
$

What if a user or group name is a string of digits?

root>useradd 1991
root>mkdir /home/1991
root>chown 1991.1991 /home/1991/
root>passwd 1991
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
root>login 1991
Password: 

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
$ 
root>deluser 1991
Removing user `1991' ...
Warning: group `1991' has no more members.
Done.
root>


root>ls
Desktop
root>cd /home/
root>ls
1991  jeffrin
root>rm -r 1991/
root>cd
root>



root>useradd 471
root>mkdir /home/471
root>chown 471.471  /home/471/
root>ls -l /home/
total 8
drwxr-xr-x  2 471     471     4096 Apr 15 17:57 471
drwxr-xr-x 24 jeffrin jeffrin 4096 Apr 15 17:25 jeffrin
root>chown +471:+471 /home/471/
root>ls -l /home/
total 8
drwxr-xr-x  2     471     471 4096 Apr 15 17:57 471
drwxr-xr-x 24 jeffrin jeffrin 4096 Apr 15 17:25 jeffrin
root>chown +471 /home/471/
root>ls -l /home/
total 8
drwxr-xr-x  2     471     471 4096 Apr 15 17:57 471
drwxr-xr-x 24 jeffrin jeffrin 4096 Apr 15 17:25 jeffrin
root>

https://www.gnu.org/software/coreutils/manual/coreutils.html#Disambiguating-names-and-IDs

Finding the number of processor units

$nproc 
2
$nproc --ignore=1
1
$grep -c ^processor /proc/cpuinfo
2
$cat /proc/cpuinfo | awk '/^processor/{print $3=$3+1}' | tail -1
2
$cat /proc/cpuinfo | awk '/^processor/{print $3}' 
0
1
$lscpu | grep CPU
CPU op-mode(s):        32-bit, 64-bit
CPU(s):                2
On-line CPU(s) list:   0,1
CPU family:            21
CPU MHz:               2800.000
CPU max MHz:           3000.0000
CPU min MHz:           1400.0000
NUMA node0 CPU(s):     0,1
$lscpu | grep "CPU(s)"
CPU(s):                2
On-line CPU(s) list:   0,1
NUMA node0 CPU(s):     0,1
$lscpu | grep "CPU(s):"
CPU(s):                2
NUMA node0 CPU(s):     0,1
$lscpu | grep ^"CPU(s):"
CPU(s):                2
$lscpu | awk 'FNR == 4 {print $2}'
2
$