Monday, August 4, 2014

Read a file backwards in Python

Below sample Python code is just one of the possible implementations for reading a file in reverse order. It's not that efficient as it reads the file one character at a time but does the job; especially, what you are looking is towards the end of the file and/or file is not too big.

import os

def ReverseRead(fname, separator=os.linesep):
    with file(fname) as f:
        f.seek(0, 2)  # seek to the end of the file
        fsize = f.tell()  # get file size
        r_cursor = 1
        while r_cursor <= fsize:
            a_line = ''
            while r_cursor <= fsize:
                f.seek(-1 * r_cursor, 2)
                r_cursor += 1
                c = f.read(1)
                if c == separator and a_line:
                    r_cursor -= 1
                    break
                a_line += c
            a_line = a_line[::-1]
            yield a_line

It's a generator function so it can be used in a loop. By default, it returns one line at each call. Here's a sample use of the code.

File to read: a.txt

$ cat delete
Line1: a b   c d
Line2:         z
Line3:

Reading the file one line at a time in reverse order:

>>> for i in ReverseRead('a.txt'):
...   print i,
...
Line3:
Line2:         z
Line1: a b   c d
>>>

Friday, June 4, 2010

Ubuntu 8.10 gdm AutoStart at Boot

/etc/rcS.d contains the scripts that are executed at boot time. These are in general symbolic links to the scripts in /etc/init.d

gdm start/stop script is found in /etc/init.d/. If you're missing the link to this script in /etc/rcS.d then it is a reason why your gdm does not start when your linux box boots.

ln -s /etc/init.d/[conf_file] /etc/rcS.d/[name_it].sh

Monday, August 17, 2009

How to Pass an Opened Socket (or File Descriptor) to a Forked Process in Python/Windows

Client Side

The client side program creates 5 threads, and each thread communicates with the server.

import socket, threading
import ctypes

NUMBER_OF_CLIENT_THREADS = 5
HOST = 'localhost'
PORT = 7777
BUF_SIZE = 100

class Client(threading.Thread):

def run(self):

buf = ctypes.create_string_buffer(BUF_SIZE)

# open a conn. to the server
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST, PORT))

# send your message and recive a response
client.send('Hello, I am {0}'.format(self.getName()))
buf.value = '\0' * BUF_SIZE
data = client.recvfrom_into(buf, BUF_SIZE)
print '\tServer:', buf.value

# say your last words
client.send('Goodbye Server!')
buf.value = '\0' * BUF_SIZE
data = client.recvfrom_into(buf, BUF_SIZE)
print '\tServer:', buf.value

# exit
client.close()


def main():

thread_list = []

for i in xrange(NUMBER_OF_CLIENT_THREADS):
thread_list.append( Client() )
thread_list[i].setName("thread-"+repr(i))
thread_list[i].start()

for thr in thread_list:
thr.join()

if __name__ == "__main__":
main()

Server Side

Server forks a new child process for each connection, and child processes communicate with the client threads.
import socket, signal, os, multiprocessing, time
from ctypes import *

#
# Structures needed to duplicate a socket:
#
kernel32 = windll.kernel32
Ws2_32 = windll.Ws2_32
msvc = cdll.msvcrt

class GUID(Structure):
_fields_ = [("Data1", c_ulong),
("Data2", c_ushort),
("Data3", c_ushort),
("Data4", c_char * 8)]

class WSAPROTOCOLCHAIN(Structure):
_fields_ = [("ChainLen", c_int),
("ChainEntries", c_ulong * 7)]

class WSAPROTOCOL_INFO(Structure):
_fields_ = [("dwServiceFlags1",c_ulong),
("dwServiceFlags2",c_ulong),
("dwServiceFlags3",c_ulong),
("dwServiceFlags4",c_ulong),
("dwProviderFlags",c_ulong),
("ProviderId",GUID),
("dwCatalogEntryId",c_ulong),
("ProtocolChain", WSAPROTOCOLCHAIN),
("iVersion",c_int),
("iAddressFamily",c_int),
("iMaxSockAddr",c_int),
("iMinSockAddr",c_int),
("iSocketType",c_int),
("iProtocol",c_int),
("iProtocolMaxOffset",c_int),
("iNetworkByteOrder",c_int),
("iSecurityScheme",c_int),
("dwMessageSize",c_ulong),
("dwProviderReserved",c_ulong),
("szProtocol",c_char* 256)]

BUF_SIZE = 100

def WorkerProcess(conn_child):

buf = create_string_buffer(BUF_SIZE)

# communicate with the parent process to duplicate the opened socket with client
pid = os.getpid()
conn_child.send(pid)

wsock_prot_info = conn_child.recv()
# (AF_INET, SOCK_STREAM, IPPROTO_TCP, x, group, flag)
sock_no = Ws2_32.WSASocketA(2, 1, 6, byref(wsock_prot_info), 0, 0)

if(sock_no == c_uint(~0)):
print "Error in duplicating the socket"
conn_child.send(1)
exit(1)

conn_child.send(0) # everthing has gone OK!

# Now we have obtained the socket, go on to communicate with the client
while 1:

buf.value = '\0' * len(buf)
ret = Ws2_32.recv(sock_no, buf, len(buf), 0)
if ret == 0 or ret == -1:
break
print 'Client:' + buf.value

buf.value = '\0' * len(buf)
buf.value = "OK"
ret = Ws2_32.send(sock_no, buf, len(buf), 0)
if ret == -1: # SOCKET_ERROR
print "Error in sending data"
break

msvc._close(sock_no)

print "Worker Process Exiting..."
exit(1)

def main():

HOST = ''
PORT = 7777
wsock_prot_info = WSAPROTOCOL_INFO()

# 1. Initialize ZFS
print "Server is starting..."

# 2. Set up the server:
server = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
server.bind ( (HOST, PORT) )
server.listen ( 5 )

# 3. Listen for client connections:
while 1:

conn, addr = server.accept()
print 'New connection with', addr

#
# WE WANT TO PASS THE OPENED SOCKET TO THE NEWLY FORKED PROCESS:
#

# 1. open a pipe to realize comm. bw parent and the forked process
conn_parent, conn_child = multiprocessing.Pipe(True)

# 2. fork a process and hand the one side of the pipe to the child
new_worker = multiprocessing.Process(target=WorkerProcess, args=(conn_child,))
new_worker.start()

# 3. Child sends back its process id
cpid = conn_parent.recv()
print "New Child Process with pid {0} to handle the new client".format(cpid)

# 4. duplicate the opened socket and obtain prorocol info structure
if Ws2_32.WSADuplicateSocketA(conn.fileno(), c_ulong(cpid), byref(wsock_prot_info)) != 0:
print "Error in duplicating the socket"

# 5. Send this structure to the child, it'll use this info to create its own handle
conn_parent.send(wsock_prot_info)

# 6. Get the confirmation from the child
ret = conn_parent.recv()
if(ret!=0):
print "Error in handing in the socket to the child process"

# 7. Close connection with the client (child will handle that) and the pipe.
conn_parent.close()
conn.close()

if __name__ == "__main__":
main()

Thursday, March 26, 2009

How to Compile Your Own Module

Below is a sample module to compile (my_module.c):
#include linux/init.h
#include linux/module.h

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Oguzhan Ozmen");
MODULE_DESCRIPTION("My simple Hello World module");

static int module_init(void){

printk(KERN_ALERT "Hello World\n");

return 0; // success
}

static void __exit module_exit(void){

printk(KERN_ALERT "Goodbye\n");
}

module_init(module_init);
module_exit(module_exit);
Within the directory where my_module.c resides in, create a Makefile whose content is as follows:
obj-m += monitor_blockio.o
Then, generate the kernel object file (.ko) using the following command:
make -C [build_dir] M=$PWD modules
Here, [build_dir] stands for the directory which contains the necessary files to build new kernel modules:
- Makefile
- .config
- module.symVers (module symbol information)
- kernel header files (include/ and include/asm)
In general,
[build_dir] is:
- /lib/modules/$(uname -r)/build OR
- /usr/src/packages/BUILD/kernel-$(uname -r)

(assuming that you are using a distro compiled kernel)

Wednesday, October 22, 2008

How to Generate a Patch File

If you need to generate a patch file for a set of file(s) residing in a directory structure or just for one file, then you can use "diff" command. You can find a very nice article in Linux Magazine named "What's the diff?". Basically, this command finds out the difference between two files.

If you want to generate a patch for a directory structure:
diff -rau "old_dir" "modified_dir" > "patch_file"

r: recursive
a: treat all files as text.
u: Output NUM (default 3) lines of unified context.
In case of two file, ignoring -r would be enough.
a

How to Prevent "sudo" from Asking a Password

Some commands like "echo 3 > /proc/sys/vm/drop_caches"* require superuser priviliges so (if you are just a user and you are a sudoer) you need to sudo.

"sudo" asks for a password. However, if you're "sudo"ing in a script then it's a problem: you wouldn't want to reveal your password as a text.

You can work around so that "sudo" doesn't require a password:
Edit "/etc/sudoers": ALL=(ALL) NOPASSWD: ALL

* NOTE:
  1. echo 1 > drop_caches : just to free "pagecache" (memory which is used to cache the user data pages)
  2. echo 2 > drop_caches: just to free dcache (which stores recently generated dentries which are created when a pathname is resolved) and inodes (which contain metadata for files).
  3. echo 3 > drop_caches: remove all caches

Sunday, October 5, 2008

AMPL/BONMIN (Linux/Ubuntu)

IMPORTANT LINKS FOR BONMIN

Below are the websites which are helpful in explaining how to download/install BONMIN in a linux box:
  • (getting started) https://projects.coin-or.org/Bonmin/wiki/GettingStarted
  • https://projects.coin-or.org/BuildTools/wiki/downloadUnix
The latest version of BONMIN can be downloaded from
  • http://www.coin-or.org/download/source/Bonmin/
CAUTION

Although, it's claimed that BONMIN is tested with "gcc version 3.* and 4.* up to 4.3", I encountered a compiler/linker error:
ERROR: ....rodata' defined in discarded section `.gnu.linkonce...
I've been using gcc-3.4.6. After googling, I found that it's because of a bug which is fixed in gcc-4.*. After switching to gcc-4.0, the error is gone.

SUMMARY

After downloading and untarring the BONMIN file, the main directory contains all the necessary tools (e.g., Bonmin, IpOpt, Cbc, CoinUtils, etc.). However, some 3rd party programs which are required for installation and run are not included (because of licencing issues).

The directories, however, for these 3rd party programs are already available:
.../Bonmin-0.100.2/ThirdParty
  • HSL
  • Blas
  • Lapack
  • ASL
You only need to download the source codes into the corresponding directories:
- Fill in "Registration Form". You don't need to activate your membership! After acquiring the username/passwd just go ahead!
- In the "Package(s) Required'' part, enter 'MA27'.
- Login the "HSL Archieve" with the acquired username and password.
- You will need the double precision versions of the MA27 (you don't need to download the dependencies such as ID05 and ZA02), MC19. In the HSL directory, you should save to files named ma27ad.f and mc19ad.f respectively.
Finally, create a new director called "build" under the main directory:
  • mkdir .../Bonmin-0.100.2/build
And, within the "build", execute the following commands
  1. ../configure -C
  2. make
  3. make test
  4. make install
"make install" will create the below directories under "build":
  • bin
  • lib
  • share
  • include
"bin" contains the executable "bonmin" and the solvers it uses: Cbc, Clp, and Ipopt. "lib" contains the neccesary libarary files for "bonmin" to run.

Create a symbolic link named "bonmin" (which points at .../Bonmin-0.100.2/build/bin/bonmin) under the directory where "ampl" executable resides so that ampl can use BONMIN as a solver.