jlm-blog
~jlm

5-Oct-2017

Tutorial for building .so files

Filed under: linux, programming — jlm @ 18:34

Exactly how one goes about building .so files* isn’t widely understood, and the documentation on it is overcomplicated IMHO. So, I figure the web needs a tutorial demonstrating how to build an extremely simple .so file. Et voilà, here’s a step by step guide for building a .so file on Linux or a similarly flavored Unix using a GNU-compatible toolchain.

We’re going to make two .o files, “call_me.o” and “die.o”, and combine them into a single “call_me_and_die” shared library. Making a library is very much like making an executable, just with some tweaks to the build commands and some extra steps at the end. To make our “call_me_and_die” library, we start the way we would with a “call_me_and_die” executable: writing a .h file for the common function signatures. File so_tut.h:

extern void call_me(void);
extern void die_die_die(void);

(more…)

11-Sep-2017

EBUSY: Another decade, and still sucking

Filed under: general, linux, programming — jlm @ 12:40

Today’s xkcd riffs a common frustration about busy files: programs that can’t do their intended operations on them rarely (if ever) specify the file that’s busy or tell the user which programs are using the file — and without that knowledge, the user can’t fix the problem.

There are tools that can help you discover those things, as I describe using ten years ago, but I’d already been running into EBUSY problems for ten years by then, and the old guard before me for another ten years beyond that. Why haven’t things improved?

Sometimes file_operation(filename) fails — hey, this happens, busy files are a thing, ain’t nothing your program can do about that. But report to the user that file_operation on filename failed for reason strerror(errno)! Not reporting the filename is just sloppy programming.

It’s not like the tools have gotten any better. What, you think it’s acceptable to make the user trace your program, looking through a haystack of every system call to find the needle which is the program’s critical failure? Is that work you’re putting on the user’s shoulders less than sticking the filename in the error message? This has sucked for two generations now. Please help making it suck less.

4-Mar-2017

twitcode #4: reverse diff — using the right tool for the job

Filed under: programming — jlm @ 20:29

Mercurial’s  hg diff  command supports a  --reverse  option which shows the regular diff output except it reverses the sense of the comparison — i.e., it goes from the “destination” to the “source” (git diff  supports this option too, but as the flag “-R”). Most of the time you want the ordinary “forward” sense, but occasionally the reverse sense comes in handy, and that’s why that option’s there. On rare occasion, I’ll even want to do this to files not under version control, but the regular system diff doesn’t support this feature.

So, after hitting this deficiency again recently, I decided to write up my own reverse-diff command which would swap its last two arguments and call diff. I started with the shell, as dealing with command arguments and calling programs is its forte. But it turned out to be surprisingly difficult to do stuff like copy the argument list or mess around with the end and near-end of the argument list, which I thought would be dead-simple operations. After futzing around with shell variables and parameters and the various options for variable/parameter expansion for something like 25 minutes, I came to my senses and did it in something like two minutes using C, where nothing’s going to interpret any kind of data as anything unless you explicitly request it to, and array manipulation is built in with clean syntax. All I had to do was swap argv[argc-1] and argv[argc-2] then execvp("diff", argv), easy peasy.

And if I golf argc and argv into c and v, then it fits in 130 chars [source]:
#include <unistd.h>
int main(int c, char**v) {
 if (c>2) { char*t=v[c-2]; v[c-2]=v[c-1]; v[c-1]=t; }
 return execvp("diff", v);
}

I could probably omit the check for ≥2 arguments, as the system diff doesn’t support the convention that a missing file argument means to use stdin (instead, it treats a filename of - (single hyphen) as representing stdin), but perhaps it’ll be used by somebody who’s installed an enhanced diff program.

I’m also amused that each of my “twitcodes” has been in a different language: shell, perl, python, and now C.

29-Dec-2016

A puzzle about C’s stdio

Filed under: programming — jlm @ 18:06

I found the C puzzles webpage by Gowri Kumar to be a very interesting collection of oddities of the C language and some of its basic libraries. If you work with C for fun or profit, I encourage you to go and give them a try. I found very few of them to produce behavior I hadn’t expected, which could be a symptom of overfamiliarity with C. I did find a few surprises though, which I felt warranted further investigation. (more…)

28-May-2016

twitcode #3: New mail in mbox

Filed under: programming — jlm @ 09:12

Once upon a time, people’s interactions with computers (those few people who got to interact with computers directly) was mostly through a teletype: a combination of a keyboard where they could type instructions to the computer and a printer where it gave the responses back to them. This model is tenaciously clung to by a handful of still-active projects such as gdb, but the bulk of its use nowadays is from command shells (bash, zsh, cmd.exe) because command-response interaction is much easier to specify, record, automate, examine, modify, and perform remotely in a teletype-style than a GUI-style.
(more…)

24-Nov-2015

twitcode #2: decoding MIME

Filed under: programming — jlm @ 12:12

Messing around with some mail handling scripts, I was surprised I didn’t find any good ways to decode MIME as a stream filter. Ten minutes later, I have 13 lines of Perl which do it in 201 characters in my normal non-terse style. It’s great for normal use, but a tiny bit of golfing fits it in a tweet’s 140-character limit:

$ cat mime_decode.pl
#!/usr/bin/perl -w
use strict; use utf8; use MIME::WordDecoder; 
binmode(STDOUT, ":utf8");
while (<>) { print mime_to_perl_string($_); }
$ wc mime_decode.pl
  4  16 137 mime_decode.pl

Good thing there was already a method which does all the real work…

4-Aug-2014

Faces are hard

Filed under: web — jlm @ 22:10

So, there’s this webcomic Prequel Adventure set in the Elder Scrolls: Oblivion universe. It’s an excellent comic, with a compelling plot and great humor. (It also is paced extremely slow, with a real-time:in-universe-time ratio that handily exceeds even that of Freefall.) The panels are drawn simply, supporting the story’s elements and the comic’s jokes, and clearly indicating that the focus is on telling a good story in a funny manner, and not on having beautiful art (another similarity with Freefall). But despite the comic’s simple drawing style, there’s one bit which Kazerad absolutely nails: Facial expressions. I mean, look at the final panel from this page.
(more…)

16-Nov-2013

… and also the wrong things with the wrong people

Filed under: web — jlm @ 18:21

G+ advertises user control over sharing on post complaining of G+ unauthorized oversharing

<SOURCE>

 
"That's what we call Irony!"

23-Dec-2012

Addressing the fragile base class problem

Filed under: programming — jlm @ 21:47

I’ve been thinking about the fragile base class problem lately. (Yes, I know it’s almost Christmas. My mind works mysteriously.) I started thinking by analogy to APIs, which the interface a superclass gives a subclass in fact is, even if it’s not called that. So, the superclass’s API changes, breaking the subclass, just like a regular API’s change can break a client. How do we deal with this with regular APIs? If we are to make a compatibility-breaking change (which introducing any member into a superclass potentially is), we version the API so that a client requesting version 1 semantics gets them while only clients written against the newer semantics will request version 2. We could do the same kind of thing with class inheritance if we mark everything with revision numbers, which we reference when inheriting.

class base@2 {
    void start@1();
    void stop@1();
    void idle@2();
};

class child@1 extends base@1 {
    void idle@1();
    void park@1();
};

Here’s our classic case of a fragile base class. child subclassed base and defined the new method idle(), then later base was extended with its own method idle(). Normally, this would cause a problem — the new stop() implementation might call idle() perhaps, and child’s idle() won’t be written with overriding a then-nonexistent base::idle() in mind. But with these revision markings, we say that child only overrides methods marked as being in revision 1 of base. So, when stop() calls idle(), it gets base::idle, not child::idle, and when park() calls idle(), the call resolution goes the other way.

The problem I see with this though, is that when going to an indirect superclass, it can be unclear which revision that should be.

class grandparent@3 {
    void method@2();
};

class parent@2 extends grandparent@2;

class child@1 extends parent@1 {
    void method@1();
};

Uh-oh. Should child’s method() override grandparent’s? If parent@1 extended grandparent@2, then yes. But if it extended grandparent@1, then no. So do we need to list the parent class revisions of every revision of the child class? I’d hope there’d be a better way. Perhaps we’d be relying on an IDE to handle the revision numbers for us, keeping them updated is just a dumb task, so in that case the IDE could maintain the manifest of parent revisions too.

20-Nov-2012

How not to do automatic updates

Filed under: linux — jlm @ 10:47

Today’s attempt at upgrading packages produced this:

Reading package lists... Error!
E: Encountered a section with no Package: header
E: Problem with MergeList /var/lib/apt/lists/extras.ubuntu.com_ubuntu_dists_precise_main_i18n_Translation-en
E: The package lists or status file could not be parsed or opened.

The contents of that file?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">  
   <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
   <META HTTP-EQUIV="refresh" CONTENT="0;url=https://login.wifiportal.co.nz">
   <TITLE>Welcome to FIVO Hotspot, Product of Natcom LTD NZ</TITLE>
</HEAD>
<BODY>

</BODY>
</HTML>

I don’t have unattended upgrades enabled on my Ubuntu laptop. Nevertheless, there’s something which goes around and replaces files in /var/lib/apt with whatever junk it gets from whatever network it happens to be connected to at random times. Can I be the only person who thinks this is a Really Bad Idea?

Powered by WordPress