2 #include <stdio.h> /* for FILE etc */
3 #include <stdlib.h> /* for malloc */
4 #include <string.h> /* for memset */
5 #include <unistd.h> /* for fork/exec */
7 #include <sys/types.h> /* for wait */
8 #include <sys/wait.h> /* for wait */
10 #include "pnd_container.h"
13 #include "pnd_logger.h"
15 static char apps_exec_runline [ 1024 ];
17 char *pnd_apps_exec_runline ( void ) {
18 return ( apps_exec_runline );
21 unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id,
22 char *rel_exec, char *rel_startdir,
24 unsigned int clockspeed, unsigned int options )
27 char s_clockspeed [ 100 ];
30 //printf ( "Entering pnd_apps_exec\n" );
49 printf ( " runscript: %s\n", pndrun );
50 printf ( " path: %s\n", fullpath );
51 printf ( " id: %s\n", unique_id );
52 printf ( " exec: %s\n", rel_exec );
53 printf ( " cwd: %s\n", rel_startdir );
54 printf ( " clock: %u\n", clockspeed );
57 memset ( argv, '\0', sizeof(char*) * 20 );
60 argv [ f++ ] = pndrun;
62 argv [ f++ ] = fullpath;
64 argv [ f++ ] = rel_exec;
67 argv [ f++ ] = rel_startdir;
74 argv [ f++ ] = unique_id;
77 snprintf ( s_clockspeed, 100, "%u", clockspeed );
78 argv [ f++ ] = s_clockspeed;
81 // skip -a (arguments) for now
83 if ( options & PND_EXEC_OPTION_NOUNION ) {
84 argv [ f++ ] = "-n"; // no union for now
87 if ( options & PND_EXEC_OPTION_NOX11 ) {
88 argv [ f++ ] = "-x"; // shut down X!
92 argv [ f++ ] = NULL; // for execv
95 if ( options & PND_EXEC_OPTION_NORUN ) {
97 bzero ( apps_exec_runline, 1024 );
98 //pnd_log ( PND_LOG_DEFAULT, "Norun %u\n", f );
99 for ( i = 0; i < ( f - 1 ); i++ ) {
100 //pnd_log ( PND_LOG_DEFAULT, "Norun %u: %s\n", i, argv [ i ] );
102 // add spacing between args
104 strncat ( apps_exec_runline, " ", 1000 );
107 // if this is for -a, we need to wrap with quotes
108 if ( i > 0 && strcmp ( argv [ i - 1 ], "-a" ) == 0 ) {
109 strncat ( apps_exec_runline, "\"", 1000 );
112 strncat ( apps_exec_runline, argv [ i ], 1000 );
114 // if this is for -a, we need to wrap with quotes
115 if ( i > 0 && strcmp ( argv [ i - 1 ], "-a" ) == 0 ) {
116 strncat ( apps_exec_runline, "\"", 1000 );
126 for ( i = 0; i < f; i++ ) {
127 printf ( "exec's argv %u [ %s ]\n", i, argv [ i ] );
133 if ( ( f = fork() ) < 0 ) {
135 } else if ( f > 0 ) {
139 execv ( pndrun, argv );
142 // by definition, either error occurred or we are the original application.
144 // do we wish to wait until the child process completes? (we don't
145 // care if it crashed, was killed, was suspended, whatever.)
146 if ( options & PND_EXEC_OPTION_BLOCK ) {
148 waitpid ( f, &status, 0 /* no options */ );
152 // printf ( "Exiting pnd_apps_exec\n" );
157 void pnd_get_ro_mountpoint ( char *fullpath, char *unique_id, char *r_mountpoint, unsigned int mountpoint_len ) {
159 if ( ! r_mountpoint ) {
163 snprintf ( r_mountpoint, mountpoint_len, "%s/%s/", PND_MOUNT_PATH, unique_id );
168 unsigned char pnd_get_appdata_path ( char *fullpath, char *unique_id, char *r_path, unsigned int path_len ) {
169 // you know, determining the 'mount point' used is sort of a pain in the rear
170 // use df <file>, skip header line, grab first token. Cheap and should work.
171 // (Rather than just assume first two path chunks in path, say, which would be pretty darned
172 // accurate, but whose to say they're not using NFS or crazy mountpoints?)
174 char cmdbuf [ 1024 ];
176 snprintf ( cmdbuf, 1023, "/bin/df %s", fullpath );
178 df = popen ( cmdbuf, "r" );
181 return ( 0 ); // tunefs: you can tune a filesystem but you can't tune a fish
184 // fetch and discard header
185 if ( ! fgets ( cmdbuf, 1023, df ) ) {
190 // grab df result line
191 if ( ! fgets ( cmdbuf, 1023, df ) ) {
199 char *ws = strchr ( cmdbuf, ' ' );
207 if ( r_path && path_len ) {
208 snprintf ( r_path, path_len, "%s/appdata/%s/", cmdbuf, unique_id );