{"id":4117,"date":"2020-05-09T00:01:07","date_gmt":"2020-05-09T07:01:07","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4117"},"modified":"2020-05-16T08:11:36","modified_gmt":"2020-05-16T15:11:36","slug":"changing-a-files-permissions","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4117","title":{"rendered":"Changing a File&#8217;s Permissions"},"content":{"rendered":"<p>In Unix-like operating systems, the <em>chmod<\/em> shell command alters a file&#8217;s permissions. From the C library, the <em>chmod()<\/em> function does the same thing.<br \/>\n<!--more--><br \/>\nThe <em>chmod()<\/em> function is prototyped in the <code>sys\/stat.h<\/code> header file, along with all those delicious defined constants and macros mentioned in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4101\">last week&#8217;s Lesson<\/a>. Here&#8217;s the <em>man<\/em> (page 2) format:<\/p>\n<p><code>int chmod(const char *path, mode_t mode);<\/code><\/p>\n<p>The <code>path<\/code> is the filename string or a full pathname to the file. It can be a regular file, directory, device, whatever. The <code>mode<\/code> argument is the same <em>mode_t<\/em> type found as the <em>st_mode<\/em> member of the <em>stat<\/em> structure filled by the <em>stat()<\/em> function.<\/p>\n<p>My advice would be to not randomly set various bits for a file&#8217;s permission (or mode) without knowing the current permissions. Therefore, I think the best approach to changing a file&#8217;s permissions is to first use the <em>stat()<\/em> function to examine the permissions, then use <em>chmod()<\/em> to and reset specific permissions. The code below follows this approach, setting the group write and other write permissions:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_05_09-Lesson.c\" rel=\"noopener noreferrer\" target=\"_blank\">2020_05_09-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;sys\/stat.h&gt;\r\n\r\nvoid output_permissions(mode_t m)\r\n{\r\n    putchar( m &amp; S_IRUSR ? 'r' : '-' );\r\n    putchar( m &amp; S_IWUSR ? 'w' : '-' );\r\n    putchar( m &amp; S_IXUSR ? 'x' : '-' );\r\n    putchar( m &amp; S_IRGRP ? 'r' : '-' );\r\n    putchar( m &amp; S_IWGRP ? 'w' : '-' );\r\n    putchar( m &amp; S_IXGRP ? 'x' : '-' );\r\n    putchar( m &amp; S_IROTH ? 'r' : '-' );\r\n    putchar( m &amp; S_IWOTH ? 'w' : '-' );\r\n    putchar( m &amp; S_IXOTH ? 'x' : '-' );\r\n    putchar('\\n');\r\n}\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    const char *filename;\r\n    struct stat fs;\r\n    int r;\r\n\r\n    if( argc&lt;2 )\r\n    {\r\n        puts(\"Filename required\");\r\n        exit(1);\r\n    }\r\n\r\n    filename = argv[1];\r\n    printf(\"Permissions for '%s':\\n\",filename);\r\n    r = stat(filename,&amp;fs);\r\n    if( r==-1)\r\n    {\r\n        fprintf(stderr,\"Error reading '%s'\\n\",filename);\r\n        exit(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* output the current permissions *\/<\/span>\r\n    puts(\"Current permissions:\");\r\n    output_permissions(fs.st_mode);\r\n\r\n    puts(\"Set group and other write permissions\");\r\n    r = chmod( filename, fs.st_mode | S_IWGRP+S_IWOTH );\r\n    if( r!=0)\r\n    {\r\n        fprintf(stderr,\"Unable to reset permissions on '%s'\\n\",filename);\r\n        exit(1);\r\n    }\r\n\r\n    puts(\"Updated permissions:\");\r\n    stat(filename,&amp;fs);\r\n    output_permissions(fs.st_mode);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>output_permissions()<\/em> function runs through the file&#8217;s <em>st_mode<\/em> value, passed in variable <code>m<\/code>. Each of the nine permissions is evaluated in a <em>putchar()<\/em> function, the ternary operator determines whether the given bit is set or reset.<\/p>\n<p>In the <em>main()<\/em> function, the <em>stat()<\/em> function at Line 33 grabs the named file&#8217;s current permissions. This value is output at Line 42 with a call to the <em>output_permissions()<\/em> function.<\/p>\n<p>At Line 45, the <em>chmod()<\/em> function performs a logical OR operation with the file&#8217;s current permissions (<code>fs.st_mode<\/code>): the <code>S_IWGRP<\/code> and <code>S_IWOTH<\/code> defined constants set new permissions for the file.<\/p>\n<p>After the permissions are changed, a second call to the <em>stat()<\/em> function is made at Line 53. The updates permissions are output. Here&#8217;s a sample run:<\/p>\n<p><code>Permissions for 'gettysburg.txt':<br \/>\nCurrent permissions:<br \/>\nrw-r--r--<br \/>\nSet group and other write permissions<br \/>\nUpdated permissions:<br \/>\nrw-rw-rw-<\/code><\/p>\n<p>The <a href=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2015\/09\/gettysburg.txt\">gettysburg.txt<\/a> file originally had permissions <code>rw-r--r--<\/code>: owner read\/write, all others read-only. The <em>chmod()<\/em> function added write permissions for group and other users, rendering the updated permissions as <code>rw-rw-rw<\/code>.<\/p>\n<p>On my system, I reset the permissions back their original settings after running the program. Typical permissions for a file you own on are <code>rw-r--r--<\/code>. The shell <em>chmod<\/em> command used to reset permissions is <strong>chmod 644<\/strong>. This command uses octal values to represent the three groups: owner, group (or wheel), and other.<\/p>\n<p>All this information ties back into an <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4052\">earlier blog post<\/a> on creating a file &#8220;in the raw.&#8221; I offer the specifics in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4125\">next week&#8217;s Lesson<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just as you can examine permissions assigned to a file, your code can alter the permissions. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4117\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-4117","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4117","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4117"}],"version-history":[{"count":8,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4117\/revisions"}],"predecessor-version":[{"id":4147,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4117\/revisions\/4147"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4117"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4117"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4117"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}