Const and pointers in C

The syntax of constant pointers in C can be confusing. Try reading from right to left, away from the variable name. E.g.

Pointer to a constant of type char:

const char *ptr_name;

Constant pointer to a variable of type char:

char *const ptr_name;

Constant pointer, to a constant of type char:

const char *const ptr_name;

Using git as a subversion interface – git-svn

Git is my favourite source control system but unfortunately some companies still use historic subversion repos that we have to put up with. This is my basic workflow when dealing with svn.

Importing the repo

Cloning the svn repo to git:
git svn clone https://address/to/svn/repo

For a very large repo this periodically failed with:
error: git-svn died of signal 13
To continue from the same spot just run:
git svn fetch

This happened quite a few times when cloning from a slow server that took all day.

Note that git-svn doesn’t recursively clone svn externals (nested repositories). There are a few complex solutions on stackoverflow, haven’t picked my favourite yet.

Pulling changes

Instead of a git pull I do:

git stash; git svn fetch; git svn rebase; git stash pop

Commiting changes

For simple projects I think a major advantage of git is the ability to easily queue commits from the command line. I use my normal process of the interactive prompt to add files and a commit message:

git add -i
git commit -m "Message"

Then instead of a git push I do:

git stash; git svn dcommit; git svn rebase; git stash pop

Bash – Loops using pipe and read

Perform some operation for every line in the output of a command, e.g. add .txt to every file in a directory:

ls /var/* | while read fname; do cp $fname $fname.txt; done

Instead of:

for fname in `ls /var/*`; do cp $fname $fname.txt; done

Neat trick I actually picked up in a job interview. Easier to read if the original command is long as it avoids the backticks, and bash is all about readability, right?? 🙂

Bash String Manipulation

Bash has some convenient string manipulation functions. I often use substring removal which is very handy for trimming suffixes and prefixes from things like file names. These operations all evaluate to a new string and don’t modify the original variable.

Suffix removal
Remove the longest match from end:
    output=${string%%suffix}
Remove the shortest match from end:
    output=${string%suffix}

Prefix removal
Remove the longest match from front:
    output=${string##prefix}
Remove the shortest match from front:
    output=${string#prefix}

Great reference for more string operations: http://tldp.org/LDP/abs/html/string-manipulation.html

Mozilla Game On: Hackable Javascript + HTML5 Game

I have submitted my entry to the Mozilla Game On competition under the ‘hackable games’ category. It can be played online now at: http://austinmarton.github.com/phys-ed/

PhysEd

I developed a basic platformer written from scratch in Javascript using HTML5 canvas and some jQuery. It has a ‘mod mode’ in which the user can view some of what is going on behind the scenes and change some of the physical parameters. Of course I ran out of time in the end but the competition was a great push to at least get a playable prototype out there.

It is released under GPLv3 so please check out or even fork the source code on github!

Linux timers using file descriptors

I recently had to add some timers to an application that was polling a list of file descriptors. The linux timers interface that notifies using file descriptors worked well. Basic example below:

/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/&gt;.
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include <fcntl.h>
#define TIMEOUT 3
#define POLL_PERIOD 1
int main(int argc, char *argv[])
{
int ret;
int fd = –1;
struct itimerspec timeout;
unsigned long long missed;
/* create new timer */
fd = timerfd_create(CLOCK_MONOTONIC, 0);
if (fd <= 0) {
printf("Failed to create timer\n");
return 1;
}
/* set to non-blocking */
ret = fcntl(fd, F_SETFL, O_NONBLOCK);
if (ret) {
printf("Failed to set to non blocking mode\n");
return 1;
}
/* set timeout */
timeout.it_value.tv_sec = TIMEOUT;
timeout.it_value.tv_nsec = 0;
timeout.it_interval.tv_sec = TIMEOUT; /* recurring */
timeout.it_interval.tv_nsec = 0;
ret = timerfd_settime(fd, 0, &timeout, NULL);
if (ret) {
printf("Failed to set timer duration\n");
return 1;
}
while (1) {
printf("Polling\n");
while (read(fd, &missed, sizeof(missed)) < 0) {
printf("No timer expiry\n");
sleep(POLL_PERIOD);
}
printf("Number of expiries missed: %lld\n", missed);
}
return 0;
}

Receiving raw packets in Linux without pcap

Since there was a lot of interest in my post on sending raw Ethernet packets, this is an example of receiving packets on a raw socket. A compiling version can be found on github: https://gist.github.com/2862515. The application that I developed this for was to receive packets sent to a specific MAC address. The main sections are explained below:

Open raw socket listening for ETHER_TYPE

	if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) {
		perror("listener: socket");	
		return -1;
	}

Set interface to promiscuous mode

	strncpy(ifopts.ifr_name, ifName, IFNAMSIZ-1);
	ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
	ifopts.ifr_flags |= IFF_PROMISC;
	ioctl(sockfd, SIOCSIFFLAGS, &ifopts);

Allow socket to be reused

	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
		perror("setsockopt");
		close(sockfd);
		exit(EXIT_FAILURE);
	}

Bind to device

	if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, IFNAMSIZ-1) == -1)	{
		perror("SO_BINDTODEVICE");
		close(sockfd);
		exit(EXIT_FAILURE);
	}

Receive on socket

	numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL);
	printf("listener: got packet %lu bytes\n", numbytes);

Print the data

	printf("\tData:");
	for (i=0; i<numbytes; i++) printf("%02x:", buf[i]);
	printf("\n");

Close socket

	close(sockfd);