Skip to main content

Win32 API vs. Linux - Round One

Before we start today's fight, we shall introduce you to the contestants, and a bit of background on each of them.

In the Red Corner, we have code written to work well with the Win32 API. The Win32 API is known for being part of Windows, and being able to kill its opponents easily, with the sheer size and complexity of itself. In the Blue Corner, we have code written to work well on Linux. Linux code being known to be quite easy to deal with, and not having heaps of levels of abstraction when it isn't neccesary.

These two come together today, to see who can write the better program that can:

  • Open a file, specified on the command line, for exclusive read only access.
  • Report if there was a problem opening the file, with an appropriate error message.
  • Close the file.

We would like to thank today's sponsor for this event, namely the Systems Programming 2 class that I am currently undertaking at University, and is making me learn how to code with the Windows API.

So that is enough, talk, lets see how the fight goes.

Windows starts off first by allowing a bit more complexity to its CreateFile() routine, but this is unfortunately useless, and not able to withstand the sheer simplicity of Linux's open() call, which beats it hands down.

In an attempt to reclaim, the match, Windows tries to claim that it can give a more superior error message handling routine, for when that file open does not work. Unfortunately, while Windows was still trying to type the function name for the routine to get the error message, Linux had already finished writing code to get and display the error message, thanks to perror(). In fact, Linux was so efficient, it decided to go one step better, and customise the error message all together.

In the end, it came down to closing the handle/file descriptor, to see if Windows would get a foot in, in this round, and it seems that it was a tie. Both Windows and Linux successfully made closing the open file nice and easy.

However, it the clear winner this round is the Linux code. <strong>Score:</strong> 2.5 - 0.5 -- Linux code wins.

To see the code used in this contest, and to agree with me that Linux definately wins this round in terms of better code/less code for this task, see the code below.

### Windows

#include <windows.h> #include <stdio.h>

int main(int argc, char *argv[]) {

System Message: WARNING/2 (<string>, line 32); backlink

Inline emphasis start-string without end-string.

System Message: ERROR/3 (<string>, line 34)

Unexpected indentation.

HANDLE hFileToRead; LPTSTR pszErrorMessageBuf; SECURITY_ATTRIBUTES lpSecurityAtrribs;

lpSecurityAtrribs.nLength = sizeof(lpSecurityAtrribs); lpSecurityAtrribs.lpSecurityDescriptor = NULL; lpSecurityAtrribs.bInheritHandle = TRUE;

if (argc < 2) {

System Message: ERROR/3 (<string>, line 44)

Unexpected indentation.
fprintf(stderr, "Syntax: %s <filename>", argv[0]); return -1;

System Message: WARNING/2 (<string>, line 46)

Block quote ends without a blank line; unexpected unindent.

}

hFileToRead = CreateFile(
argv[1], GENERIC_READ, 0, lpSecurityAtrribs, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFileToRead == INVALID_HANDLE_VALUE) {

System Message: ERROR/3 (<string>, line 54)

Unexpected indentation.
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(), 0, (LPTSTR)&pstrErrorMessageBuf, 0, NULL);
fprintf(stderr, "Could not open file '%s': [%d] %s", argv[1],
GetLastError(), pstrErrorMessageBuf);

System Message: WARNING/2 (<string>, line 59)

Definition list ends without a blank line; unexpected unindent.

LocalFree(pstrErrorMessageBuf); return -1;

System Message: WARNING/2 (<string>, line 61)

Block quote ends without a blank line; unexpected unindent.

} else

System Message: ERROR/3 (<string>, line 63)

Unexpected indentation.
printf("File successfully opened.n");
if (!CloseHandle(hFileToRead))
fprintf(stderr, "Error closing file...n");

return 0;

System Message: WARNING/2 (<string>, line 69)

Block quote ends without a blank line; unexpected unindent.

}

### Linux

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <unistd.h>

int main(int argc, char *argv[]) {

System Message: WARNING/2 (<string>, line 81); backlink

Inline emphasis start-string without end-string.

System Message: ERROR/3 (<string>, line 83)

Unexpected indentation.

int fd;

if (argc < 2) {

System Message: ERROR/3 (<string>, line 87)

Unexpected indentation.
fprintf(stderr, "Syntax: %s <filename>n", argv[0]); return -1;

System Message: WARNING/2 (<string>, line 89)

Block quote ends without a blank line; unexpected unindent.

}

fd = open(argv[1], O_EXCL|O_RDONLY); if (fd == -1) {

System Message: ERROR/3 (<string>, line 94)

Unexpected indentation.
fprintf(stderr, "Could not open file '%s': [%d] %sn",
argv[1], errno, strerror(errno));

System Message: WARNING/2 (<string>, line 96)

Definition list ends without a blank line; unexpected unindent.

return -1;

System Message: WARNING/2 (<string>, line 97)

Block quote ends without a blank line; unexpected unindent.

} else

System Message: ERROR/3 (<string>, line 99)

Unexpected indentation.
printf("File successfully opened.n");
if (close(fd))
fprintf(stderr, "Error closing file...n");

return 0;

System Message: WARNING/2 (<string>, line 105)

Block quote ends without a blank line; unexpected unindent.

}