<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Alex on Linux&#187; Code library</title>
	<atom:link href="http://www.alexonlinux.com/category/code-library/feed" rel="self" type="application/rss+xml" />
	<link>http://www.alexonlinux.com</link>
	<description></description>
	<lastBuildDate>Sun, 25 Jul 2010 10:00:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Recursively deleting symbolic link and what it points to</title>
		<link>http://www.alexonlinux.com/recursively-deleting-symbolic-link-and-what-it-points-to</link>
		<comments>http://www.alexonlinux.com/recursively-deleting-symbolic-link-and-what-it-points-to#comments</comments>
		<pubDate>Mon, 01 Feb 2010 08:52:59 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Code library]]></category>
		<category><![CDATA[Programming Articles]]></category>
		<category><![CDATA[Short articles]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1703</guid>
		<description><![CDATA[Recently I looked for a solution to this little problem. how do you, programmatically, delete a symbolic link and a file that it points to? One problem that you should take care of when tackling this problem, is that symbolic link can point to a symbolic link. Then symbolic link should also point to symbolic [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/hex-dump-functions' rel='bookmark' title='Permanent Link: Hex dump functions'>Hex dump functions</a></li>
<li><a href='http://www.alexonlinux.com/direct-io-in-python' rel='bookmark' title='Permanent Link: Direct IO in Python'>Direct IO in Python</a></li>
<li><a href='http://www.alexonlinux.com/how-less-processes-its-input' rel='bookmark' title='Permanent Link: How less processes its input'>How less processes its input</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Recently I looked for a solution to this little problem. how do you, programmatically, delete a symbolic link and a file that it points to?</p>
<p>One problem that you should take care of when tackling this problem, is that symbolic link can point to a symbolic link. Then symbolic link should also point to symbolic link. And once again, and again and again&#8230;</p>
<p><span id="more-1703"></span>So what can we do about it? First, lets start with <em>lstat</em>() system all. It will tell us is the file we&#8217;re interested in, is actually a symbolic link. To be more precise, <em>st_mode</em> field in <em>struct stat</em> will have flag S_IFLNK if specified file is a symbolic link. Note that it should be <em>lstat</em>() and not <em>stat</em>() &#8211; the later will return information about file the link points to and not about the link.</p>
<p>Next step is to call <em>readlink</em>(). This system call returns name of the file pointed to by specified symbolic link.</p>
<p>Finally, you should repeat the process recursively, for the pointed to file. Here is the code that does it:</p>
<pre class="brush:cpp">int recursive_deleter(const char* filename)
{
  struct stat st;
  char buffer[1024];

  if (lstat(filename, &amp;st)) {
    perror("stat");
    return -1;
  }     

  if (st.st_mode &amp; S_IFLNK == S_IFLNK) {
    memset(buffer, 0, sizeof(buffer));
    if (readlink(filename, buffer, sizeof(buffer)) &lt; 0) {
      perror("readlink");
      return -1;
    }           

    printf("File %s is a symbolic link to %s\n", filename, buffer);

    if (recursive_deleter(buffer))
      return 0;
  }     

  printf("Deleting %s\n", filename);

  if (unlink(filename)) {
    perror("unlink");
    return -1;
  }     

  return 0;
}
</pre>
<p>Have fun!</p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/hex-dump-functions' rel='bookmark' title='Permanent Link: Hex dump functions'>Hex dump functions</a></li>
<li><a href='http://www.alexonlinux.com/direct-io-in-python' rel='bookmark' title='Permanent Link: Direct IO in Python'>Direct IO in Python</a></li>
<li><a href='http://www.alexonlinux.com/how-less-processes-its-input' rel='bookmark' title='Permanent Link: How less processes its input'>How less processes its input</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/recursively-deleting-symbolic-link-and-what-it-points-to/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rethinking linked list insertion</title>
		<link>http://www.alexonlinux.com/rethinking-linked-list-insertion</link>
		<comments>http://www.alexonlinux.com/rethinking-linked-list-insertion#comments</comments>
		<pubDate>Sat, 19 Dec 2009 12:24:36 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code library]]></category>
		<category><![CDATA[Short articles]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1658</guid>
		<description><![CDATA[There is one nice thing in looking for a new job. That is, you meet lots of new people and have a chance to learn from them. For example in one of the companies I was asked about something called anti-debugging. I didn&#8217;t have a clue what that is and had to ask for an [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/pthread-mutex-vs-pthread-spinlock' rel='bookmark' title='Permanent Link: pthread mutex vs pthread spinlock'>pthread mutex vs pthread spinlock</a></li>
<li><a href='http://www.alexonlinux.com/todo-list' rel='bookmark' title='Permanent Link: Todo list'>Todo list</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>There is one nice thing in looking for a new job. That is, you meet lots of new people and have a chance to learn from them. For example in one of the companies I was asked about something called anti-debugging. I didn&#8217;t have a clue what that is and had to ask for an explanation. Apparently, this is a set of techniques used to fool a debugger and make the code undebuggable.</p>
<p>Anyway, here&#8217;s something else that I learned during one of the interviews.</p>
<p><span id="more-1658"></span>I was asked to implement insertion into a linked list in <em>C</em>. Each list node has a number (<em>num</em>). Numbers in the list should be sorted in ascending order &#8211; node with lowest number should be first. Here is my naive implementation.</p>
<pre class="brush:cpp">void list_insert(int num)
{
        list_node_t *n, *tmp, *prev;

        n = allocate_node();
        n-&gt;num = num;

        if (!head) {
                head = n;
                n-&gt;next = NULL;
        } else {
                tmp = head;
                prev = NULL;
                while (tmp) {
                        if (tmp-&gt;num &gt;= n-&gt;num) {
                                if (prev == NULL) {
                                        head-&gt;next = n;
                                        n-&gt;next = NULL;
                                } else {
                                        n-&gt;next = tmp;
                                        prev-&gt;next = n;
                                }

                                break;
                        }

                        prev = tmp;
                        tmp = tmp-&gt;next;
                }

                if (!tmp) {
                        n-&gt;next = NULL;
                        prev-&gt;next = n;
                }
        }
}</pre>
<p>Yeah, well it is pretty long, but that&#8217;s how you do it, right? You have to make sure that the list is not empty (line 8 ) &#8211; if it is empty, then new node should be placed at the head of the list. Then we have to find right place for the new node and insert it into its position (lines 14-29). Finally, if we didn&#8217;t find a good position for the new node, we should put the node at the end of the list (lines 31-34).</p>
<p>When I showed this to the examiner he asked me to rethink the routine. In particular he didn&#8217;t like number of <em>if</em> statements. After an hour of discussing various optimizations, this is what we came up with.</p>
<pre class="brush:cpp">void list_insert(int num)
{
        list_node_t **tmp, *n;

        n = allocate_node();
        n-&gt;num = num;

        tmp = &amp;head;
        while (*tmp) {
                if ((*tmp)-&gt;num &gt;= n-&gt;num)
                        break;
                tmp = &amp;(*tmp)-&gt;next;
        }

/*
        (*tmp) = n;
       n-&gt;next = (*tmp)-&gt;next;
*/

/*
        The code in the comment above is broken. Thanks to jagan
        for pointing this out. Here's the right code.
*/
        n->next = *tmp;
        *tmp = n;
}</pre>
<p>There are several things that make this version better.</p>
<p>First of all, instead of having a pointer to current node (<em>tmp</em>) and previous node (<em>prev</em>), we have one pointer that corresponds to pointer to previous node. This way we can always get to the current node via <em>next</em> field in the previous node. Thus we don&#8217;t need two pointers anymore.</p>
<p>Also, this version uses pointer to pointer to node to traverse through the list. We don&#8217;t insert the node in the while loop anymore. Purpose of the while loop is to find right place for the new node. This spares <em>if</em> statement that tests if the list is empty and <em>if </em>statement in the loop.</p>
<p>Finally, once <em>tmp</em> points to the right place, we insert the node.</p>
<p>Second version runs faster too. I did a small program that tests both versions and it appears that the later version is something like 5% faster.</p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/pthread-mutex-vs-pthread-spinlock' rel='bookmark' title='Permanent Link: pthread mutex vs pthread spinlock'>pthread mutex vs pthread spinlock</a></li>
<li><a href='http://www.alexonlinux.com/todo-list' rel='bookmark' title='Permanent Link: Todo list'>Todo list</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/rethinking-linked-list-insertion/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Hex dump functions</title>
		<link>http://www.alexonlinux.com/hex-dump-functions</link>
		<comments>http://www.alexonlinux.com/hex-dump-functions#comments</comments>
		<pubDate>Sun, 07 Jun 2009 18:00:31 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Code library]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1386</guid>
		<description><![CDATA[This post starts a new category of posts called Code library. In this category I will post useful code snippets. I hope you&#8217;ll find them as useful as I do. I use two functions below quiet often. Both functions do hexadecimal dump of given buffer. First function is in C. Second function is in Python. [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/recursively-deleting-symbolic-link-and-what-it-points-to' rel='bookmark' title='Permanent Link: Recursively deleting symbolic link and what it points to'>Recursively deleting symbolic link and what it points to</a></li>
<li><a href='http://www.alexonlinux.com/direct-io-in-python' rel='bookmark' title='Permanent Link: Direct IO in Python'>Direct IO in Python</a></li>
<li><a href='http://www.alexonlinux.com/how-to-handle-sigsegv-but-also-generate-core-dump' rel='bookmark' title='Permanent Link: How to handle SIGSEGV, but also generate a core dump'>How to handle SIGSEGV, but also generate a core dump</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>This post starts a new category of posts called <em>Code library</em>. In this category I will post useful code snippets. I hope you&#8217;ll find them as useful as I do.</p>
<p>I use two functions below quiet often. Both functions do hexadecimal dump of given buffer. First function is in C. Second function is in Python. Enjoy.</p>
<p><span id="more-1386"></span></p>
<pre class="brush:cpp">void hex_dump(char *data, int size, char *caption)
{
	int i; // index in data...
	int j; // index in line...
	char temp[8];
	char buffer[128];
	char *ascii;

	memset(buffer, 0, 128);

	printf("---------&gt; %s &lt;--------- (%d bytes from %p)\n", caption, size, data);

	// Printing the ruler...
	printf("        +0          +4          +8          +c            0   4   8   c   \n");

	// Hex portion of the line is 8 (the padding) + 3 * 16 = 52 chars long
	// We add another four bytes padding and place the ASCII version...
	ascii = buffer + 58;
	memset(buffer, ' ', 58 + 16);
	buffer[58 + 16] = '\n';
	buffer[58 + 17] = '\0';
	buffer[0] = '+';
	buffer[1] = '0';
	buffer[2] = '0';
	buffer[3] = '0';
	buffer[4] = '0';
	for (i = 0, j = 0; i &lt; size; i++, j++)
	{
		if (j == 16)
		{
			printf("%s", buffer);
			memset(buffer, ' ', 58 + 16);

			sprintf(temp, "+%04x", i);
			memcpy(buffer, temp, 5);

			j = 0;
		}

		sprintf(temp, "%02x", 0xff &amp; data[i]);
		memcpy(buffer + 8 + (j * 3), temp, 2);
		if ((data[i] &gt; 31) &amp;&amp; (data[i] &lt; 127))
			ascii[j] = data[i];
		else
			ascii[j] = '.';
	}

	if (j != 0)
		printf("%s", buffer);
}</pre>
<p>And the Python version. Python version is a bit smarter &#8211; it allows you to specify output stream.</p>
<pre class="brush:py">def DumpBuffer(self, buf, length, caption="", dest=sys.stdout):
	def GetPrintableChar(str):
		if str.isalpha():
			return str
		else:
			return '.'

	dest.write('---------&gt; %s &lt;--------- (%d bytes)\n' % (caption, length))
	dest.write('       +0          +4          +8          +c           0   4   8   c\n')
	i = 0
	while i &lt; length:
		if length - i &gt; 16:
			l = 16
		else:
			l = length - i

		dest.write('+%04x  ' % i)
		s = ' '.join(["%02x" % ord(c) for c in buf[i:i + l]])
		dest.write(s)
		sp = 49 - len(s)
		dest.write(' ' * sp)
		s = ''.join(["%c" % GetPrintableChar(c) for c in buf[i:i + l]])
		dest.write(s)
		dest.write('\n')

		i = i + 16</pre>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/recursively-deleting-symbolic-link-and-what-it-points-to' rel='bookmark' title='Permanent Link: Recursively deleting symbolic link and what it points to'>Recursively deleting symbolic link and what it points to</a></li>
<li><a href='http://www.alexonlinux.com/direct-io-in-python' rel='bookmark' title='Permanent Link: Direct IO in Python'>Direct IO in Python</a></li>
<li><a href='http://www.alexonlinux.com/how-to-handle-sigsegv-but-also-generate-core-dump' rel='bookmark' title='Permanent Link: How to handle SIGSEGV, but also generate a core dump'>How to handle SIGSEGV, but also generate a core dump</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/hex-dump-functions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
