Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It seems to me this is straightforward to do using a POSIX <a href="http://man7.org/linux/man-pages/man7/shm_overview.7.html">shared memory</a> object:</p> <blockquote> <p>POSIX shared memory objects have kernel persistence: a shared memory object will exist until the system is shut down, or until all processes have unmapped the object and it has been deleted with shm_unlink</p> </blockquote> <p>Whenever your program launches it can <code>shm_open</code> a new object with some consistent name and set the owner to <code>root</code>. The object needn't contain any particular value. POSIX requires that all shared memory objects persist until reboot unless manually destroyed (which only its owner or creator can do...which in this case is the root user).</p> <p>Whenever your program launches it first checks if such a shared memory object already exists having root as the owner. Since only root could create such an object, and only root or a reboot could destroy it, you can thus know for certain whether your program has been launched since the last reboot, save the only possible circumvention being the root user invoking <code>shm_unlink</code> on the object manually.</p> <p>I wrote a test-and-set function below that <strong>should</strong> do exactly what you need. And it works except for the ownership setting/detection: for some unknown reason both calls to <code>shmctl</code> are failing on my system, saying "invalid argument". The <code>man</code> page for <code>shmctl</code> says the <code>EINVAL</code> error indicates either an invalid memory object identifier or an invalid command. But the <code>IPC_SET</code> and <code>IPC_STAT</code> commands are certainly valid, and you can watch the program's output to see the valid object identifier that is being created and/or opened each time.</p> <pre class="lang-c prettyprint-override"><code>#include &lt;sys/shm.h&gt; #include &lt;sys/mman.h&gt; #include &lt;sys/types.h&gt; #include &lt;fcntl.h&gt; #include &lt;sys/stat.h&gt; #include &lt;sys/ipc.h&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; int rebooted_test_and_set() { int err; int rebooted; struct shmid_ds shmst; // create object if nonexistent, returning failure if already exists int shmid = shm_open("/bootcheck", O_CREAT | O_EXCL); if (shmid != -1) { fprintf(stderr, "bootcheck object did not exist, so created: %d\n", shmid); // object did not exist, so system has been rebooted rebooted = 1; // set owner to root, and no permissions for anyone shmst.shm_perm.uid = 0; shmst.shm_perm.gid = 0; shmst.shm_perm.mode = 0; if ((err = shmctl(shmid, IPC_SET, &amp;shmst)) == -1) { perror("shmctl: shmctl failed to set owner and permissions for bootcheck object"); exit(1); } } else { // object already exists, so reopen with read access and verify that the owner is root shmid = shm_open("/bootcheck", O_RDONLY); if (shmid == -1) { perror("shm_open: failed, perhaps due to insufficient privileges"); exit(1); } fprintf(stderr, "bootcheck object (%d) exists, so checking ownership\n", shmid); if ((err = shmctl(shmid, IPC_STAT, &amp;shmst)) == -1) { perror("shmctl: shmctl failed"); exit(1); } if (shmst.shm_perm.uid == 0) { // yes, the bootcheck owner is root, // so we are confident the system has NOT been rebooted since last launch rebooted = 0; } else { // uh oh, looks like someone created the object illegitimately. // since that is only possible if the root-owned object did not exist, // therefore we know that it never did exist since the last reboot rebooted = 1; } } return rebooted; } // for debugging purposes ONLY, so I don't have to keep rebooting to clear the object: void rebooted_clear() { if (shm_unlink("/bootcheck") == -1) { perror("shm_unlink: failed, probably due to insufficient privileges or object nonexistent"); exit(1); } } int main() { int rebooted = rebooted_test_and_set(); printf("rebooted since last launch: %d\n", rebooted); return 0; } </code></pre> <p>If anyone has any clues, I'm stumped. Some information and examples for POSIX shared memory <a href="http://www.cs.cf.ac.uk/Dave/C/node27.html">here</a>.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload