+ exec* functions
[meinos.git] / apps / lib / libmeinos / proc.c
blobcacc8539c736df90c91b089c5e798465324de2b5
1 /*
2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <syscall.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/shm.h>
25 #include <unistd.h>
26 #include <pack.h>
28 size_t _fs_pack_filehandles(pack_t buf);
29 void _fs_unpack_filehandles(pack_t buf);
31 /**
32 * Gets name of a process
33 * @param pid PID of process
34 * @return Name of process (can be passed to free())
36 char *getname(pid_t pid) {
37 size_t size = syscall_call(SYSCALL_PROC_GETNAME,3,pid,NULL,0);
38 char *buf = malloc(size);
39 syscall_call(SYSCALL_PROC_GETNAME,3,pid,buf,size);
40 return buf;
43 /**
44 * Gets list of used pages
45 * @param pid PID of process to get list from
46 * @param _num_pages Reference for number of pages
47 * @return Array with pages (must be free()'d)
49 void **proc_mempagelist(pid_t pid,size_t *_num_pages) {
50 ssize_t num_pages = syscall_call(SYSCALL_PROC_MEMPAGELIST,3,pid,NULL,0);
51 if (num_pages>0) {
52 void **pages = malloc(num_pages*sizeof(void*));
53 *_num_pages = syscall_call(SYSCALL_PROC_MEMPAGELIST,3,pid,pages,num_pages);
54 return pages;
56 else return NULL;
59 /**
60 * Pack process data
61 * @param argv Argument vector
62 * @param env Enviroment variables
63 * @return Var for new process
65 int proc_pack_procdata(char **argv,char **env,char *cwd,mode_t cmask) {
66 size_t argv_size,fh_size,cwd_size,env_size,cmask_size,i;
67 int shmid,argc,env_num;
68 void *shmbuf;
69 pack_t buf;
71 // prepare argv
72 argv_size = sizeof(argc);
73 if (argv!=NULL) {
74 for (argc=0;argv[argc];argc++) argv_size += strlen(argv[argc])+1;
76 else argc = 0;
78 // prepare env
79 env_size = sizeof(env_num);
80 if (env!=NULL) {
81 for (env_num=0;env[env_num];env_num++) env_size += strlen(env[env_num]);
83 else env_num = 0;
85 // prepare current workdir
86 if (cwd==NULL) cwd = "/";
87 cwd_size = strlen(cwd)+1;
89 // prepare creation mask
90 cmask_size = sizeof(cmask);
92 // prepare filehandles
93 fh_size = _fs_pack_filehandles(NULL);
95 // allocate space
96 shmid = shmget(IPC_PRIVATE,argv_size+env_size+cwd_size+cmask_size+fh_size,0);
97 if (shmid!=-1) {
98 shmbuf = shmat(shmid,NULL,0);
99 if (shmbuf!=NULL) {
100 buf = pack_create(shmbuf);
102 // pack argv
103 packi(buf,argc);
104 for (i=0;i<argc;i++) packstr(buf,argv[i]);
105 // pack env
106 packi(buf,env_num);
107 for (i=0;i<env_num;i++) packstr(buf,env[i]);
109 // pack current workdir
110 packstr(buf,cwd);
112 // pack creation mask
113 packi(buf,cmask);
115 // pack filehandles
116 _fs_pack_filehandles(buf);
118 // release space
119 pack_destroy(buf);
120 shmdt(shmbuf);
121 return shmid;
123 else shmctl(shmid,IPC_RMID,NULL);
126 return -1;
130 * Unpack process data
131 * @param var Var
132 * @param argv Reference for argument vector
133 * @param argc Reference for argument count
134 * @return Var for new process
136 int proc_unpack_procdata(int var,int *argc,char ***argv) {
137 int ret;
138 size_t i,env_num;
139 char *cwd;
140 void *shmbuf;
141 pack_t buf;
142 mode_t cmask;
144 // get space
145 shmbuf = shmat(var,NULL,0);
146 if (shmbuf!=NULL) {
147 buf = pack_create(shmbuf);
149 // unpack argv
150 unpacki(buf,argc);
151 *argv = malloc(*argc*sizeof(char*));
152 for (i=0;i<*argc;i++) unpackstr(buf,(*argv)+i);
153 (*argv)[i] = NULL;
155 // unpack env
156 unpacki(buf,&env_num);
157 environ = malloc(env_num*sizeof(char*));
158 for (i=0;i<env_num;i++) {
159 char *tmp;
160 unpackstr(buf,&tmp);
161 environ[i] = strdup(tmp);
163 environ[i] = NULL;
165 // unpack current workdir
166 unpackstr(buf,&cwd);
167 chdir(cwd);
169 // unpack creation mask
170 unpacki(buf,&cmask);
171 umask(cmask);
173 // unpack filehandles
174 _fs_unpack_filehandles(buf);
176 // free space
177 pack_destroy(buf);
178 shmdt(shmbuf);
179 ret = var;
181 else ret = -1;
183 shmctl(var,IPC_RMID,NULL);
185 return ret;