int shim_do_pipe2 (int * filedes, int flags) { if (!filedes) return -EINVAL; int ret = 0; struct shim_handle * hdl1 = get_new_handle(); struct shim_handle * hdl2 = get_new_handle(); if (!hdl1 || !hdl2) { ret = -ENOMEM; goto out; } hdl1->type = TYPE_PIPE; set_handle_fs(hdl1, &pipe_builtin_fs); hdl1->flags = O_RDONLY; hdl1->acc_mode = MAY_READ; hdl2->type = TYPE_PIPE; set_handle_fs(hdl2, &pipe_builtin_fs); hdl2->flags = O_WRONLY; hdl2->acc_mode = MAY_WRITE; if ((ret = create_pipes(&hdl1->info.pipe.pipeid, &hdl1->pal_handle, &hdl2->pal_handle, &hdl1->uri, flags)) < 0) goto out; qstrcopy(&hdl2->uri, &hdl2->uri); flags = flags & O_CLOEXEC ? FD_CLOEXEC : 0; int vfd1 = set_new_fd_handle(hdl1, flags, NULL); int vfd2 = set_new_fd_handle(hdl2, flags, NULL); if (vfd1 < 0 || vfd2 < 0) { if (vfd1 >= 0) { struct shim_handle * tmp = detach_fd_handle(vfd1, NULL, NULL); if (tmp) close_handle(tmp); } if (vfd2 >= 0) { struct shim_handle * tmp = detach_fd_handle(vfd2, NULL, NULL); if (tmp) close_handle(tmp); } goto out; } filedes[0] = vfd1; filedes[1] = vfd2; out: if (hdl1) put_handle(hdl1); if (hdl2) put_handle(hdl2); return ret; }
int shim_do_openat (int dfd, const char * filename, int flags, int mode) { if (!filename || test_user_string(filename)) return -EFAULT; if (*filename == '/') return shim_do_open(filename, flags, mode); struct shim_dentry * dir = NULL; int ret = 0; if ((ret = path_startat(dfd, &dir)) < 0) return ret; struct shim_handle * hdl = get_new_handle(); if (!hdl) { ret = -ENOMEM; goto out; } ret = open_namei(hdl, dir, filename, flags, mode, NULL); if (ret < 0) goto out_hdl; ret = set_new_fd_handle(hdl, flags & O_CLOEXEC ? FD_CLOEXEC : 0, NULL); out_hdl: put_handle(hdl); out: put_dentry(dir); return ret; }
Tcl_DString *tcl_krb5_create_object(Tcl_Interp *interp, char *type, ClientData datum) { Tcl_HashTable *table; Tcl_DString *handle; Tcl_HashEntry *entry; int entry_created = 0; if (! (table = get_hash_table(interp, type))) { return 0; } if (! (handle = get_new_handle(interp, type))) { return 0; } if (! (entry = Tcl_CreateHashEntry(table, handle, &entry_created))) { Tcl_SetResult(interp, "error creating hash entry", TCL_STATIC); Tcl_DStringFree(handle); return TCL_ERROR; } assert(entry_created); Tcl_SetHashValue(entry, datum); return handle; }
int shim_do_open (const char * file, int flags, mode_t mode) { if (!file || !(*file)) return -EINVAL; struct shim_handle * hdl = get_new_handle(); if (!hdl) return -ENOMEM; int ret = 0; ret = open_namei(hdl, NULL, file, flags, mode, NULL); if (ret < 0) goto out; ret = set_new_fd_handle(hdl, flags & O_CLOEXEC ? FD_CLOEXEC : 0, NULL); out: put_handle(hdl); return ret; }
int shim_do_truncate (const char * path, loff_t length) { struct shim_dentry * dent = NULL; int ret = 0; if (!path || test_user_string(path)) return -EFAULT; if ((ret = path_lookupat(NULL, path, 0, &dent, NULL)) < 0) return ret; struct shim_mount * fs = dent->fs; if (!fs || !fs->d_ops || !fs->d_ops->open) { ret = -EBADF; goto out; } if (!fs->fs_ops->truncate) { ret = -EROFS; goto out; } struct shim_handle * hdl = get_new_handle(); if (!hdl) { ret = -ENOMEM; goto out; } hdl->fs = fs; if ((ret = fs->d_ops->open(hdl, dent, O_WRONLY)) < 0) goto out_handle; ret = fs->fs_ops->truncate(hdl, length); flush_handle(hdl); out_handle: put_handle(hdl); out: return ret; }
static inline int init_exec_handle (struct shim_thread * thread) { if (!PAL_CB(executable)) return 0; struct shim_handle * exec = get_new_handle(); if (!exec) return -ENOMEM; set_handle_fs(exec, &chroot_builtin_fs); qstrsetstr(&exec->uri, PAL_CB(executable), strlen(PAL_CB(executable))); exec->type = TYPE_FILE; exec->flags = O_RDONLY; exec->acc_mode = MAY_READ; lock(thread->lock); thread->exec = exec; unlock(thread->lock); return 0; }
int init_important_handles (void) { struct shim_thread * thread = get_cur_thread(); if (thread->handle_map) goto done; struct shim_handle_map * handle_map = get_cur_handle_map(thread); if (!handle_map) { handle_map = get_new_handle_map(INIT_HANDLE_MAP_SIZE); if (!handle_map) return -ENOMEM; set_handle_map(thread, handle_map); } lock(handle_map->lock); if (handle_map->fd_size < 3) { if (!__enlarge_handle_map(handle_map, INIT_HANDLE_MAP_SIZE)) { unlock(handle_map->lock); return -ENOMEM; } } struct shim_handle * hdl = NULL; int ret; for (int fd = 0 ; fd < 3 ; fd++) if (!HANDLE_ALLOCATED(handle_map->map[fd])) { if (!hdl) { hdl = get_new_handle(); if (!hdl) return -ENOMEM; if ((ret = init_tty_handle(hdl, fd)) < 0) { put_handle(hdl); return ret; } } else { get_handle(hdl); } __set_new_fd_handle(&handle_map->map[fd], fd, hdl, 0); put_handle(hdl); if (fd != 1) hdl = NULL; } else { if (fd == 1) hdl = handle_map->map[fd]->handle; } if (handle_map->fd_top == FD_NULL || handle_map->fd_top < 2) handle_map->fd_top = 2; unlock(handle_map->lock); done: init_exec_handle(thread); return 0; }
void on_live_fw_activate(LiVESMenuItem *menuitem, livespointer user_data) { char *com,*tmp; int cardno; int cache=1024; int new_file=mainw->first_free_file; int response; char *fifofile=lives_strdup_printf("%s/firew.%d",prefs->tmpdir,capable->mainpid); char *fname; LiVESWidget *card_dialog; mainw->open_deint=FALSE; card_dialog=create_cdtrack_dialog(5,NULL); response=lives_dialog_run(LIVES_DIALOG(card_dialog)); if (response==LIVES_RESPONSE_CANCEL) { lives_widget_destroy(card_dialog); lives_free(fifofile); return; } cardno=(int)mainw->fx1_val; lives_widget_destroy(card_dialog); if (lives_list_find(fw_cards,LIVES_INT_TO_POINTER(cardno))) { lives_free(fifofile); do_card_in_use_error(); return; } fname=lives_strdup_printf(_("Firewire card %d"),cardno); if (!get_new_handle(new_file,fname)) { lives_free(fifofile); lives_free(fname); return; } fw_cards=lives_list_append(fw_cards,LIVES_INT_TO_POINTER(cardno)); mainw->current_file=new_file; cfile->deinterlace=mainw->open_deint; unlink(fifofile); mkfifo(fifofile,S_IRUSR|S_IWUSR); com=lives_strdup_printf("%s open_fw_card \"%s\" %d %d \"%s\"",prefs->backend,cfile->handle,cardno,cache,fifofile); mainw->com_failed=FALSE; lives_system(com,FALSE); lives_free(com); if (mainw->com_failed) { mainw->com_failed=FALSE; lives_free(fname); lives_free(fifofile); return; } if (!open_yuv4m_inner(fifofile,fname,new_file,YUV4_TYPE_FW,cardno)) { lives_free(fname); lives_free(fifofile); return; } lives_snprintf(cfile->type,40,"%s",fname); d_print((tmp=lives_strdup_printf(_("Opened firewire card %d"),cardno))); lives_free(tmp); lives_free(fname); lives_free(fifofile); }
void on_live_tvcard_activate(LiVESMenuItem *menuitem, livespointer user_data) { int cardno=0; int new_file=mainw->first_free_file; int response; char *com,*tmp; char *fifofile=lives_strdup_printf("%s/tvpic.%d",prefs->tmpdir,capable->mainpid); char *chanstr; char *devstr; char *fname; LiVESWidget *card_dialog; lives_tvcardw_t *tvcardw; mainw->open_deint=FALSE; card_dialog=create_cdtrack_dialog(4,NULL); tvcardw=(lives_tvcardw_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(card_dialog),"tvcard_data"); response=lives_dialog_run(LIVES_DIALOG(card_dialog)); if (response==LIVES_RESPONSE_CANCEL) { lives_widget_destroy(card_dialog); lives_free(fifofile); lives_free(tvcardw); return; } cardno=(int)mainw->fx1_val; chanstr=lives_strdup_printf("%d",(int)mainw->fx2_val); if (lives_list_find(mainw->videodevs,LIVES_INT_TO_POINTER(cardno))) { lives_widget_destroy(card_dialog); do_card_in_use_error(); lives_free(chanstr); lives_free(fifofile); lives_free(tvcardw); return; } fname=lives_strdup_printf(_("TV card %d"),cardno); if (!get_new_handle(new_file,fname)) { lives_widget_destroy(card_dialog); lives_free(chanstr); lives_free(fifofile); lives_free(fname); lives_free(tvcardw); return; } devstr=lives_strdup_printf("/dev/video%d",cardno); if (!check_dev_busy(devstr)) { lives_widget_destroy(card_dialog); do_dev_busy_error(fname); lives_free(devstr); lives_free(chanstr); lives_free(fifofile); lives_free(fname); lives_free(tvcardw); return; } mainw->videodevs=lives_list_append(mainw->videodevs,LIVES_INT_TO_POINTER(cardno)); mainw->current_file=new_file; cfile->deinterlace=mainw->open_deint; unlink(fifofile); mkfifo(fifofile,S_IRUSR|S_IWUSR); if (!tvcardw->use_advanced) { com=lives_strdup_printf("%s open_tv_card \"%s\" \"%s\" \"%s\" \"%s\"",prefs->backend,cfile->handle,chanstr, devstr,fifofile); } else { double fps=0.; char *driver=NULL,*outfmt=NULL; int width=0,height=0; int input=lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(tvcardw->spinbuttoni)); if (!lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(tvcardw->radiobuttond))) { width=lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(tvcardw->spinbuttonw)); height=lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(tvcardw->spinbuttonh)); fps=lives_spin_button_get_value(LIVES_SPIN_BUTTON(tvcardw->spinbuttonf)); } driver=lives_combo_get_active_text(LIVES_COMBO(tvcardw->combod)); outfmt=lives_combo_get_active_text(LIVES_COMBO(tvcardw->comboo)); com=lives_strdup_printf("%s open_tv_card \"%s\" \"%s\" \"%s\" \"%s\" %d %d %d %.3f \"%s\" \"%s\"", prefs->backend,cfile->handle,chanstr, devstr,fifofile,input,width,height,fps,driver,outfmt); lives_free(driver); lives_free(outfmt); } lives_widget_destroy(card_dialog); lives_free(tvcardw); mainw->com_failed=FALSE; lives_system(com,FALSE); lives_free(com); if (mainw->com_failed) { mainw->com_failed=FALSE; lives_free(fname); lives_free(chanstr); lives_free(fifofile); lives_free(devstr); return; } if (!open_yuv4m_inner(fifofile,fname,new_file,YUV4_TYPE_TV,cardno)) { lives_free(fname); lives_free(chanstr); lives_free(fifofile); lives_free(devstr); return; } lives_snprintf(cfile->type,40,"%s",fname); d_print((tmp=lives_strdup_printf(_("Opened TV card %d (%s)"),cardno,devstr))); lives_free(tmp); lives_free(fname); lives_free(chanstr); lives_free(devstr); lives_free(fifofile); }
void on_open_yuv4m_activate(LiVESMenuItem *menuitem, livespointer user_data) { // open a general yuvmpeg stream // start "playing" but open frames in yuv4mpeg format on stdin int old_file=mainw->current_file,new_file=mainw->first_free_file; char *tmp; char *filename; char *fname; char *audio_real,*audio_fake; if (menuitem && !do_yuv4m_open_warning()) return; fname=lives_strdup(_("yuv4mpeg stream")); if (!get_new_handle(new_file,fname)) { lives_free(fname); return; } mainw->current_file=new_file; if (!strlen(prefs->yuvin)) filename=lives_build_filename(prefs->tmpdir,"stream.yuv",NULL); else filename=lives_strdup(prefs->yuvin); mkfifo(filename,S_IRUSR|S_IWUSR); if (!open_yuv4m_inner(filename,fname,new_file,YUV4_TYPE_GENERIC,0)) { close_current_file(old_file); lives_free(filename); lives_free(fname); return; } lives_free(fname); if (!lives_yuv_stream_start_read(cfile)) { close_current_file(old_file); lives_free(filename); return; } new_file=mainw->current_file; lives_snprintf(cfile->type,40,"%s",_("yu4mpeg stream in")); d_print((tmp=lives_strdup_printf(_("Opened yuv4mpeg stream on %s"),filename))); lives_free(tmp); lives_free(filename); d_print(_("Audio: ")); if (cfile->achans==0) { d_print(_("none\n")); } else { d_print((tmp=lives_strdup_printf(P_("%d Hz %d channel %d bps\n","%d Hz %d channels %d bps\n",cfile->achans), cfile->arate,cfile->achans,cfile->asampsize))); lives_free(tmp); } // if not playing, start playing if (mainw->playing_file==-1) { // temp kludge, symlink audiodump.pcm to wav file, then pretend we are playing // an opening preview . Doesn't work with fifo. // and we dont really care if it doesnt work // but what it means is, if we have an audio file or stream at // "prefs->tmpdir/audiodump.pcm" we will try to play it // real is tmpdir/audiodump.pcm audio_real=lives_build_filename(prefs->tmpdir,"audiodump.pcm",NULL); // fake is tmpdir/handle/audiodump.pcm audio_fake=lives_build_filename(prefs->tmpdir,cfile->handle,"audiodump.pcm",NULL); #ifndef IS_MINGW // fake file will go away when we close the current clip lives_system((tmp=lives_strdup_printf("/bin/ln -s \"%s\" \"%s\" >/dev/null 2>&1", audio_real,audio_fake)),TRUE); #else // TODO #endif lives_free(audio_real); lives_free(audio_fake); lives_free(tmp); // start playing play_file(); mainw->noswitch=FALSE; } // TODO - else... if (mainw->current_file!=old_file&&mainw->current_file!=new_file) old_file=mainw->current_file; // we could have rendered to a new file mainw->current_file=new_file; // close this temporary clip close_current_file(old_file); }
static int __add_msg_handle (unsigned long key, IDTYPE msqid, bool owned, struct shim_msg_handle ** msghdl) { struct hlist_head * key_head = (key != IPC_PRIVATE) ? &msgq_key_hlist[MSGQ_HASH(key)] : NULL; struct hlist_head * qid_head = msqid ? &msgq_qid_hlist[MSGQ_HASH(msqid)] : NULL; struct shim_msg_handle * tmp; struct hlist_node * pos; if (key_head) hlist_for_each_entry(tmp, pos, key_head, key_hlist) if (tmp->msqkey == key) { if (tmp->msqid == msqid) { if (msghdl) *msghdl = tmp; return 0; } return -EEXIST; } if (qid_head) hlist_for_each_entry(tmp, pos, qid_head, qid_hlist) if (tmp->msqid == msqid) { if (key) tmp->msqkey = key; if (msghdl) *msghdl = tmp; return 0; } struct shim_handle * hdl = get_new_handle(); if (!hdl) return -ENOMEM; struct shim_msg_handle * msgq = &hdl->info.msg; hdl->type = TYPE_MSG; msgq->msqkey = key; msgq->msqid = msqid; msgq->owned = owned; msgq->deleted = false; msgq->currentsize = 0; msgq->event = DkSynchronizationEventCreate(0); msgq->queue = malloc(MSG_QOBJ_SIZE * DEFAULT_MSG_QUEUE_SIZE); msgq->queuesize = DEFAULT_MSG_QUEUE_SIZE; msgq->queueused = 0; msgq->freed = NULL; msgq->ntypes = 0; msgq->maxtypes = INIT_MSG_TYPE_SIZE; msgq->types = malloc(sizeof(struct msg_type) * INIT_MSG_TYPE_SIZE); INIT_LIST_HEAD(&msgq->list); get_handle(hdl); list_add_tail(&msgq->list, &msgq_list); INIT_HLIST_NODE(&msgq->key_hlist); if (key_head) { get_handle(hdl); hlist_add_head(&msgq->key_hlist, key_head); } INIT_HLIST_NODE(&msgq->qid_hlist); if (qid_head) { get_handle(hdl); hlist_add_head(&msgq->qid_hlist, qid_head); } if (!msghdl) { put_handle(hdl); return 0; } *msghdl = msgq; return 0; }
int shim_do_socketpair (int domain, int type, int protocol, int * sv) { if (domain != AF_UNIX) return -EAFNOSUPPORT; if (type != SOCK_STREAM) return -EPROTONOSUPPORT; if (!sv) return -EINVAL; int ret = 0; struct shim_handle * hdl1 = get_new_handle(); struct shim_handle * hdl2 = get_new_handle(); if (!hdl1 || !hdl2) { ret = -ENOMEM; goto out; } struct shim_sock_handle * sock1 = &hdl1->info.sock; struct shim_sock_handle * sock2 = &hdl2->info.sock; hdl1->type = TYPE_SOCK; set_handle_fs(hdl1, &socket_builtin_fs); hdl1->flags = O_RDONLY; hdl1->acc_mode = MAY_READ|MAY_WRITE; sock1->domain = domain; sock1->sock_type = type & ~(SOCK_NONBLOCK|SOCK_CLOEXEC); sock1->protocol = protocol; sock1->sock_state = SOCK_ACCEPTED; hdl2->type = TYPE_SOCK; set_handle_fs(hdl2, &socket_builtin_fs); hdl1->flags = O_WRONLY; hdl2->acc_mode = MAY_READ|MAY_WRITE; sock2->domain = domain; sock2->sock_type = type & ~(SOCK_NONBLOCK|SOCK_CLOEXEC); sock2->protocol = protocol; sock2->sock_state = SOCK_CONNECTED; if ((ret = create_pipes(&sock1->addr.un.pipeid, &hdl1->pal_handle, &hdl2->pal_handle, &hdl1->uri, type & SOCK_NONBLOCK ? O_NONBLOCK : 0)) < 0) goto out; sock2->addr.un.pipeid = sock1->addr.un.pipeid; qstrcopy(&hdl2->uri, &hdl1->uri); int flags = type & SOCK_CLOEXEC ? FD_CLOEXEC : 0; int vfd1 = set_new_fd_handle(hdl1, flags, NULL); int vfd2 = set_new_fd_handle(hdl2, flags, NULL); if (vfd1 < 0 || vfd2 < 0) { if (vfd1 >= 0) { struct shim_handle * tmp = detach_fd_handle(vfd1, NULL, NULL); if (tmp) close_handle(tmp); } if (vfd2 >= 0) { struct shim_handle * tmp = detach_fd_handle(vfd2, NULL, NULL); if (tmp) close_handle(tmp); } goto out; } sv[0] = vfd1; sv[1] = vfd2; out: if (hdl1) put_handle(hdl1); if (hdl2) put_handle(hdl2); return ret; }